Risorse utili per le Macchine a stati.
+In questi esercizi vengono presentati alcuni paradigmi di base per la creazione
+di macchine a stato con Arduino. Vengono proposti esempi con FSM singole e FSM
+doppie concorrenti, per altri esempi pratici con semplici cicli IF, gestione degli eventi esterni / interni si puo' guardare anche il codice del progetto "Luci per Aerei RC":
+- http://aerei.piffa.net/repo/esempi/base_th_3stati/base_th_3stati.ino
+- http://aerei.piffa.net/esempi/2017/02/15/throttle-fsm.html
+- http://aerei.piffa.net/esempi/2017/02/20/alettoni-fsm.html
+- http://aerei.piffa.net/repo/aerei/
+
Tutorials
===========
* https://www.sparkfun.com/news/1801
+* http://digitaldiy.io/articles/mcu-programming/general-programming/500-finite-state-+machines#.VT0r1s90yh3
+* http://www.gammon.com.au/forum/?id=12316
+* https://github.com/JChristensen/Button/blob/master/Examples/LongPress/LongPress.pde
+* http://www.thebox.myzen.co.uk/Tutorial/State_Machine.html
+
+Teoria
+========
+* https://en.wikipedia.org/wiki/Finite-state_machine
+* https://en.wikipedia.org/wiki/Nondeterministic_finite_automaton
+* https://en.wikipedia.org/wiki/Deterministic_finite_automaton#Complete_and_incomplete
+* http://43oh.com/2017/02/how-to-implement-finite-state-machines-using-energia/
* http://playground.arduino.cc/Code/Enum
* https://www.arduino.cc/en/Reference/SwitchCase
+* https://learn.adafruit.com/multi-tasking-the-arduino-part-1
--- /dev/null
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta charset="utf-8"/>
+<meta name="generator" content="Docutils 0.13.1: http://docutils.sourceforge.net/" />
+<title>FSM</title>
+<style type="text/css">
+
+/* Minimal style sheet for the HTML output of Docutils. */
+/* */
+/* :Author: Günter Milde, based on html4css1.css by David Goodger */
+/* :Id: $Id: minimal.css 7952 2016-07-26 18:15:59Z milde $ */
+/* :Copyright: © 2015 Günter Milde. */
+/* :License: Released under the terms of the `2-Clause BSD license`_, */
+/* in short: */
+/* */
+/* Copying and distribution of this file, with or without modification, */
+/* are permitted in any medium without royalty provided the copyright */
+/* notice and this notice are preserved. */
+/* */
+/* This file is offered as-is, without any warranty. */
+/* */
+/* .. _2-Clause BSD license: http://www.spdx.org/licenses/BSD-2-Clause */
+
+/* This CSS2.1_ stylesheet defines rules for Docutils elements without */
+/* HTML equivalent. It is required to make the document semantic visible. */
+/* */
+/* .. _CSS2.1: http://www.w3.org/TR/CSS2 */
+/* .. _validates: http://jigsaw.w3.org/css-validator/validator$link */
+
+/* alignment of text and inline objects inside block objects*/
+.align-left { text-align: left; }
+.align-right { text-align: right; }
+.align-center { clear: both; text-align: center; }
+.align-top { vertical-align: top; }
+.align-middle { vertical-align: middle; }
+.align-bottom { vertical-align: bottom; }
+
+/* titles */
+h1.title, p.subtitle {
+ text-align: center;
+}
+p.admonition-title,
+p.topic-title,
+p.sidebar-title,
+p.rubric,
+p.system-message-title {
+ font-weight: bold;
+}
+h1 + p.subtitle,
+h1 + p.section-subtitle {
+ font-size: 1.6em;
+}
+h2 + p.section-subtitle { font-size: 1.28em; }
+p.subtitle,
+p.section-subtitle,
+p.sidebar-subtitle {
+ font-weight: bold;
+ margin-top: -0.5em;
+}
+p.sidebar-title,
+p.rubric {
+ font-size: larger;
+}
+p.rubric { color: maroon; }
+a.toc-backref {
+ color: black;
+ text-decoration: none; }
+
+/* Warnings, Errors */
+div.caution p.admonition-title,
+div.attention p.admonition-title,
+div.danger p.admonition-title,
+div.error p.admonition-title,
+div.warning p.admonition-title,
+div.system-messages h1,
+div.error,
+span.problematic,
+p.system-message-title {
+ color: red;
+}
+
+/* inline literals */
+span.docutils.literal {
+ font-family: monospace;
+ white-space: pre-wrap;
+}
+/* do not wraph at hyphens and similar: */
+.literal > span.pre { white-space: nowrap; }
+
+/* Lists */
+
+/* compact and simple lists: no margin between items */
+.simple li, .compact li,
+.simple ul, .compact ul,
+.simple ol, .compact ol,
+.simple > li p, .compact > li p,
+dl.simple > dd, dl.compact > dd {
+ margin-top: 0;
+ margin-bottom: 0;
+}
+
+/* Table of Contents */
+div.topic.contents { margin: 0; }
+ul.auto-toc {
+ list-style-type: none;
+ padding-left: 1.5em; }
+
+/* Enumerated Lists */
+ol.arabic { list-style: decimal }
+ol.loweralpha { list-style: lower-alpha }
+ol.upperalpha { list-style: upper-alpha }
+ol.lowerroman { list-style: lower-roman }
+ol.upperroman { list-style: upper-roman }
+
+dt span.classifier { font-style: italic }
+dt span.classifier:before {
+ font-style: normal;
+ margin: 0.5em;
+ content: ":";
+}
+
+/* Field Lists and drivatives */
+/* bold field name, content starts on the same line */
+dl.field-list > dt,
+dl.option-list > dt,
+dl.docinfo > dt,
+dl.footnote > dt,
+dl.citation > dt {
+ font-weight: bold;
+ clear: left;
+ float: left;
+ margin: 0;
+ padding: 0;
+ padding-right: 0.5em;
+}
+/* Offset for field content (corresponds to the --field-name-limit option) */
+dl.field-list > dd,
+dl.option-list > dd,
+dl.docinfo > dd {
+ margin-left: 9em; /* ca. 14 chars in the test examples */
+}
+/* start field-body on a new line after long field names */
+dl.field-list > dd > *:first-child,
+dl.option-list > dd > *:first-child
+{
+ display: inline-block;
+ width: 100%;
+ margin: 0;
+}
+/* field names followed by a colon */
+dl.field-list > dt:after,
+dl.docinfo > dt:after {
+ content: ":";
+}
+
+/* Bibliographic Fields (docinfo) */
+pre.address { font: inherit; }
+dd.authors > p { margin: 0; }
+
+/* Option Lists */
+dl.option-list { margin-left: 40px; }
+dl.option-list > dt { font-weight: normal; }
+span.option { white-space: nowrap; }
+
+/* Footnotes and Citations */
+dl.footnote.superscript > dd {margin-left: 1em; }
+dl.footnote.brackets > dd {margin-left: 2em; }
+dl > dt.label { font-weight: normal; }
+a.footnote-reference.brackets:before,
+dt.label > span.brackets:before { content: "["; }
+a.footnote-reference.brackets:after,
+dt.label > span.brackets:after { content: "]"; }
+a.footnote-reference.superscript,
+dl.footnote.superscript > dt.label {
+ vertical-align: super;
+ font-size: smaller;
+}
+dt.label > span.fn-backref { margin-left: 0.2em; }
+dt.label > span.fn-backref > a { font-style: italic; }
+
+/* Line Blocks */
+div.line-block { display: block; }
+div.line-block div.line-block {
+ margin-top: 0;
+ margin-bottom: 0;
+ margin-left: 40px;
+}
+
+/* Figures, Images, and Tables */
+.figure.align-left,
+img.align-left,
+object.align-left,
+table.align-left {
+ margin-right: auto;
+}
+.figure.align-center,
+img.align-center,
+object.align-center {
+ margin-left: auto;
+ margin-right: auto;
+ display: block;
+}
+table.align-center {
+ margin-left: auto;
+ margin-right: auto;
+}
+.figure.align-right,
+img.align-right,
+object.align-right,
+table.align-right {
+ margin-left: auto;
+}
+/* reset inner alignment in figures and tables */
+div.align-left, div.align-center, div.align-right,
+table.align-left, table.align-center, table.align-right
+{ text-align: inherit }
+
+/* Admonitions and System Messages */
+div.admonition,
+div.system-message,
+div.sidebar{
+ margin: 40px;
+ border: medium outset;
+ padding-right: 1em;
+ padding-left: 1em;
+}
+
+/* Sidebar */
+div.sidebar {
+ width: 30%;
+ max-width: 26em;
+ float: right;
+ clear: right;
+}
+
+/* Text Blocks */
+div.topic,
+pre.literal-block,
+pre.doctest-block,
+pre.math,
+pre.code {
+ margin-right: 40px;
+ margin-left: 40px;
+}
+pre.code .ln { color: gray; } /* line numbers */
+
+/* Tables */
+table { border-collapse: collapse; }
+td, th {
+ border-style: solid;
+ border-color: silver;
+ padding: 0 1ex;
+ border-width: thin;
+}
+td > p:first-child, th > p:first-child { margin-top: 0; }
+td > p, th > p { margin-bottom: 0; }
+
+table > caption {
+ text-align: left;
+ margin-bottom: 0.25em
+}
+
+table.borderless td, table.borderless th {
+ border: 0;
+ padding: 0;
+ padding-right: 0.5em /* separate table cells */
+}
+
+</style>
+<style type="text/css">
+
+/* CSS31_ style sheet for the output of Docutils HTML writers. */
+/* Rules for easy reading and pre-defined style variants. */
+/* */
+/* :Author: Günter Milde, based on html4css1.css by David Goodger */
+/* :Id: $Id: plain.css 7952 2016-07-26 18:15:59Z milde $ */
+/* :Copyright: © 2015 Günter Milde. */
+/* :License: Released under the terms of the `2-Clause BSD license`_, */
+/* in short: */
+/* */
+/* Copying and distribution of this file, with or without modification, */
+/* are permitted in any medium without royalty provided the copyright */
+/* notice and this notice are preserved. */
+/* */
+/* This file is offered as-is, without any warranty. */
+/* */
+/* .. _2-Clause BSD license: http://www.spdx.org/licenses/BSD-2-Clause */
+/* .. _CSS3: http://www.w3.org/TR/CSS3 */
+
+
+/* Document Structure */
+/* ****************** */
+
+/* "page layout" */
+body {
+ padding: 0 5%;
+ margin: 8px 0;
+}
+div.document {
+ line-height:1.3;
+ counter-reset: table;
+ /* counter-reset: figure; */
+ /* avoid long lines --> better reading */
+ /* OTOH: lines should not be too short because of missing hyphenation, */
+ max-width: 50em;
+ margin: auto;
+}
+
+/* Sections */
+
+/* Transitions */
+
+hr.docutils {
+ width: 80%;
+ margin-top: 1em;
+ margin-bottom: 1em;
+ clear: both;
+}
+
+/* Paragraphs */
+/* ========== */
+
+/* vertical space (parskip) */
+p, ol, ul, dl,
+div.line-block,
+table{
+ margin-top: 0.5em;
+ margin-bottom: 0.5em;
+}
+h1, h2, h3, h4, h5, h6,
+dl > dd {
+ margin-bottom: 0.5em;
+}
+
+/* Lists */
+/* ========== */
+
+/* Definition Lists */
+
+dl > dd p:first-child { margin-top: 0; }
+/* :last-child is not part of CSS 2.1 (introduced in CSS 3) */
+/* dl > dd p:last-child { margin-bottom: 0; } */
+
+/* lists nested in definition lists */
+/* :only-child is not part of CSS 2.1 (introduced in CSS 3) */
+dd > ul:only-child, dd > ol:only-child { padding-left: 1em; }
+
+/* Description Lists */
+/* styled like in most dictionaries, encyclopedias etc. */
+dl.description > dt {
+ font-weight: bold;
+ clear: left;
+ float: left;
+ margin: 0;
+ padding: 0;
+ padding-right: 0.5em;
+}
+
+/* Field Lists */
+
+/* example for custom field-name width */
+dl.field-list.narrow > dd {
+ margin-left: 5em;
+}
+/* run-in: start field-body on same line after long field names */
+dl.field-list.run-in > dd p {
+ display: block;
+}
+
+/* Bibliographic Fields */
+
+/* generally, bibliographic fields use special definition list dl.docinfo */
+/* but dedication and abstract are placed into "topic" divs */
+div.abstract p.topic-title {
+ text-align: center;
+}
+div.dedication {
+ margin: 2em 5em;
+ text-align: center;
+ font-style: italic;
+}
+div.dedication p.topic-title {
+ font-style: normal;
+}
+
+/* Citations */
+dl.citation dt.label {
+ font-weight: bold;
+}
+span.fn-backref {
+ font-weight: normal;
+}
+
+/* Text Blocks */
+/* ============ */
+
+/* Literal Blocks */
+pre.literal-block, pre.doctest-block,
+pre.math, pre.code {
+ margin-left: 1.5em;
+ margin-right: 1.5em
+}
+
+/* Block Quotes */
+
+blockquote,
+div.topic {
+ margin-left: 1.5em;
+ margin-right: 1.5em
+}
+blockquote > table,
+div.topic > table {
+ margin-top: 0;
+ margin-bottom: 0;
+}
+blockquote p.attribution,
+div.topic p.attribution {
+ text-align: right;
+ margin-left: 20%;
+}
+
+/* Tables */
+/* ====== */
+
+/* th { vertical-align: bottom; } */
+
+table tr { text-align: left; }
+
+/* "booktabs" style (no vertical lines) */
+table.booktabs {
+ border: 0;
+ border-top: 2px solid;
+ border-bottom: 2px solid;
+ border-collapse: collapse;
+}
+table.booktabs * {
+ border: 0;
+}
+table.booktabs th {
+ border-bottom: thin solid;
+}
+
+/* numbered tables (counter defined in div.document) */
+table.numbered > caption:before {
+ counter-increment: table;
+ content: "Table " counter(table) ": ";
+ font-weight: bold;
+}
+
+/* Explicit Markup Blocks */
+/* ====================== */
+
+/* Footnotes and Citations */
+/* ----------------------- */
+
+/* line on the left */
+dl.footnote {
+ padding-left: 1ex;
+ border-left: solid;
+ border-left-width: thin;
+}
+
+/* Directives */
+/* ---------- */
+
+/* Body Elements */
+/* ~~~~~~~~~~~~~ */
+
+/* Images and Figures */
+
+/* let content flow to the side of aligned images and figures */
+.figure.align-left,
+img.align-left,
+object.align-left {
+ display: block;
+ clear: left;
+ float: left;
+ margin-right: 1em
+}
+.figure.align-right,
+img.align-right,
+object.align-right {
+ display: block;
+ clear: right;
+ float: right;
+ margin-left: 1em
+}
+/* Stop floating sidebars, images and figures at section level 1,2,3 */
+h1, h2, h3 { clear: both; }
+
+/* Sidebar */
+
+/* Move into the margin. In a layout with fixed margins, */
+/* it can be moved into the margin completely. */
+div.sidebar {
+ width: 30%;
+ max-width: 26em;
+ margin-left: 1em;
+ margin-right: -5.5%;
+ background-color: #ffffee ;
+}
+
+/* Code */
+
+pre.code, code { background-color: #eeeeee }
+pre.code .ln { color: gray; } /* line numbers */
+/* basic highlighting: for a complete scheme, see */
+/* http://docutils.sourceforge.net/sandbox/stylesheets/ */
+pre.code .comment, code .comment { color: #5C6576 }
+pre.code .keyword, code .keyword { color: #3B0D06; font-weight: bold }
+pre.code .literal.string, code .literal.string { color: #0C5404 }
+pre.code .name.builtin, code .name.builtin { color: #352B84 }
+pre.code .deleted, code .deleted { background-color: #DEB0A1}
+pre.code .inserted, code .inserted { background-color: #A3D289}
+
+/* Math */
+/* styled separately (see math.css for math-output=HTML) */
+
+/* Epigraph */
+/* Highlights */
+/* Pull-Quote */
+/* Compound Paragraph */
+/* Container */
+
+/* can be styled in a custom stylesheet */
+
+/* Document Header and Footer */
+
+div.footer, div.header {
+ clear: both;
+ font-size: smaller;
+}
+
+/* Inline Markup */
+/* ============= */
+
+/* Emphasis */
+/* em */
+/* Strong Emphasis */
+/* strong */
+/* Interpreted Text */
+/* span.interpreted */
+/* Title Reference */
+/* cite */
+/* Inline Literals */
+/* possible values: normal, nowrap, pre, pre-wrap, pre-line */
+/* span.docutils.literal { white-space: pre-wrap; } */
+
+/* Hyperlink References */
+a { text-decoration: none; }
+
+/* External Targets */
+/* span.target.external */
+/* Internal Targets */
+/* span.target.internal */
+/* Footnote References */
+/* a.footnote-reference */
+/* Citation References */
+/* a.citation-reference */
+
+</style>
+</head>
+<body>
+<div class="document" id="fsm">
+<h1 class="title">FSM</h1>
+
+<p>Risorse utili per le Macchine a stati.</p>
+<p>In questi esercizi vengono presentati alcuni paradigmi di base per la creazione
+di macchine a stato con Arduino. Vengono proposti esempi con FSM singole e FSM
+doppie concorrenti, per altri esempi pratici con semplici cicli IF, gestione degli eventi esterni / interni si puo' guardare anche il codice del progetto "Luci per Aerei RC":
+- <a class="reference external" href="http://aerei.piffa.net/repo/esempi/base_th_3stati/base_th_3stati.ino">http://aerei.piffa.net/repo/esempi/base_th_3stati/base_th_3stati.ino</a>
+- <a class="reference external" href="http://aerei.piffa.net/esempi/2017/02/15/throttle-fsm.html">http://aerei.piffa.net/esempi/2017/02/15/throttle-fsm.html</a>
+- <a class="reference external" href="http://aerei.piffa.net/esempi/2017/02/20/alettoni-fsm.html">http://aerei.piffa.net/esempi/2017/02/20/alettoni-fsm.html</a>
+- <a class="reference external" href="http://aerei.piffa.net/repo/aerei/">http://aerei.piffa.net/repo/aerei/</a></p>
+<div class="section" id="tutorials">
+<h1>Tutorials</h1>
+<ul class="simple">
+<li><p><a class="reference external" href="https://www.sparkfun.com/news/1801">https://www.sparkfun.com/news/1801</a></p></li>
+<li><p><a class="reference external" href="http://digitaldiy.io/articles/mcu-programming/general-programming/500-finite-state-+machines#.VT0r1s90yh3">http://digitaldiy.io/articles/mcu-programming/general-programming/500-finite-state-+machines#.VT0r1s90yh3</a></p></li>
+<li><p><a class="reference external" href="http://www.gammon.com.au/forum/?id=12316">http://www.gammon.com.au/forum/?id=12316</a></p></li>
+<li><p><a class="reference external" href="https://github.com/JChristensen/Button/blob/master/Examples/LongPress/LongPress.pde">https://github.com/JChristensen/Button/blob/master/Examples/LongPress/LongPress.pde</a></p></li>
+<li><p><a class="reference external" href="http://www.thebox.myzen.co.uk/Tutorial/State_Machine.html">http://www.thebox.myzen.co.uk/Tutorial/State_Machine.html</a></p></li>
+</ul>
+</div>
+<div class="section" id="teoria">
+<h1>Teoria</h1>
+<ul class="simple">
+<li><p><a class="reference external" href="https://en.wikipedia.org/wiki/Finite-state_machine">https://en.wikipedia.org/wiki/Finite-state_machine</a></p></li>
+<li><p><a class="reference external" href="https://en.wikipedia.org/wiki/Nondeterministic_finite_automaton">https://en.wikipedia.org/wiki/Nondeterministic_finite_automaton</a></p></li>
+<li><p><a class="reference external" href="https://en.wikipedia.org/wiki/Deterministic_finite_automaton#Complete_and_incomplete">https://en.wikipedia.org/wiki/Deterministic_finite_automaton#Complete_and_incomplete</a></p></li>
+<li><p><a class="reference external" href="http://43oh.com/2017/02/how-to-implement-finite-state-machines-using-energia/">http://43oh.com/2017/02/how-to-implement-finite-state-machines-using-energia/</a></p></li>
+</ul>
+</div>
+<div class="section" id="elementi">
+<h1>Elementi</h1>
+<ul class="simple">
+<li><p><a class="reference external" href="http://playground.arduino.cc/Code/Enum">http://playground.arduino.cc/Code/Enum</a></p></li>
+<li><p><a class="reference external" href="https://www.arduino.cc/en/Reference/SwitchCase">https://www.arduino.cc/en/Reference/SwitchCase</a></p></li>
+<li><p><a class="reference external" href="https://learn.adafruit.com/multi-tasking-the-arduino-part-1">https://learn.adafruit.com/multi-tasking-the-arduino-part-1</a></p></li>
+</ul>
+</div>
+</div>
+</body>
+</html>
+++ /dev/null
-/*
- Blink FSM
-
- Accensione e spegnimanto di un LED utilizzando
- una FSM 2 stati statici.
-
-Costrutto switch basato su uno struct.
-
- */
-
-// Dichiarazione variabili
-int led = 13;
-int pausa = 500; // Variabile richiambile nel corso dell'esecuzione
-
-void setup() {
- // Inizializziamo il PIN 13 come OUTPUT
- pinMode(led, OUTPUT);
-}
-
-enum fsm_stati { // Stati della FMS
- on,
- off
-};
-
-fsm_stati stato;
-
-void loop() {
- switch (stato){
- case on :
- digitalWrite(led, HIGH); // Mette il PIN del LED in stato acceso
- delay(pausa); // Aspetta un secondo (mille millisecondi)
-
- stato = off ; // Setta il prossimo state
- break;
-
- case off:
- digitalWrite(led, LOW); // Mette il PIN del LED in stato spento
- delay(pausa); // Aspetta mezzo secondo
-
- stato = on ;
- break;
- }
-}
+++ /dev/null
-/*
- Blink FSM
-
- Accensione e spegnimanto di un LED utilizzando
- una FSM con 4 stati, statici e di transizione.
-
-Costrutto switch basato su uno struct.
-
- */
-
-// Dichiarazione variabili
-int led = 11; // PWM
-int pausa = 1000; // Variabile richiambile nel corso dell'esecuzione
-byte lum = 0 ;
-
-void setup() {
- // Inizializziamo il PIN 13 come OUTPUT
- pinMode(led, OUTPUT);
-}
-
-enum fsm_stati { // Stati della FMS
- on, // Statico
- to_off, // Transizione
- off,
- to_on
-};
-
-fsm_stati stato ;
-
-void loop() {
- switch (stato) {
- case on :
- // Operativa: Machine
- digitalWrite(led, HIGH); // Mette il PIN del LED in stato acceso
- delay(pausa);
-
- // Stati
- stato = to_off ; // Setta il prossimo state
- lum = 255;
- break;
-
- case to_off :
- while (lum > 0) {
- lum-- ;
- analogWrite(led, lum); // Mette il PIN del LED in stato acceso
- delay(1);
- }
-
- stato = off ; // Setta il prossimo state
- break;
-
- case off:
- digitalWrite(led, LOW); // Mette il PIN del LED in stato spento
- delay(pausa);
-
- stato = to_on ;
- lum = 0;
- break;
-
- case to_on :
- while (lum < 255) {
- lum++ ;
- analogWrite(led, lum); // Mette il PIN del LED in stato acceso
- delay(1);
- }
-
- stato = on ; // Setta il prossimo state
- break;
- }
-}
-
-/* Domande:
-
- 1.Cosa comporta l'uso della funzione delay?
- 2.Come si puo' modificare lo sketch per poter eseguire piu' conpiti contemporaneamente?
-
-Esercizi successivi:
-- Creare una FSM con un LED RGB avente due stati Red e Green, una transizione yellow tra i due
-- Creare una FSM per la gestione di un semaforo
- (esempio disponibile in sketchbook_andrea/advanced_projects/state_machine )
-
- .
- .
- .
- .
- .
- .
- .
- .
- .
- .
- .
- .
- .
- .
- .
- .
- .
- .
- .
- .
- Soluzioni:
-
- 1.Delay rende il codice blocking, null'altro puo' essere eseguito durante i delay
- 2.Si potrebbe utilizzare millis(), vedi esercizi multitasking
-*/
Accensione e spegnimanto di un LED utilizzando
una FSM con 4 stati, statici e di transizione.
-Costrutto switch basato su uno struct.
+Costrutto switch basato su un enum:
*/
pinMode(led, OUTPUT);
}
-enum fsm_stati { // Stati della FMS
+enum fsm_stati: byte { // Stati della FMS, explicit type cast
on, // Statico
to_off, // Transizione
off,
to_on
-};
+} stato ; // denominazione di una variabile
-fsm_stati stato ;
void loop() {
switch (stato) {
Un singolo semaforo costruito col paradigma delle macchine a stato.
Viene utilizzato un oggetto della libreria common per gestire il LED.
+
+- Schema per un led RGB: https://lab.piffa.net/schemi/rgb.jpg
+
*/
#include <common.h>
int pausa = 3000;
red
};
-states_available state ;
+states_available state = red;
void setup() {
case turn_red :
led.Yellow();
- delay(pausa/3);
- led.Red();
- delay(pausa);
+ delay(pausa / 3);
state = red ;
break;
case red :
+ led.Red();
delay(pausa);
state = turn_green ;
break;
+++ /dev/null
-/*
- Incrocio RGB
-
- Un incrocio costituito da due strade, una principale e una secondaria.
- La via viene concessa al secondario alla pressione di un bottone,
- il secondario cambia automaticamente dopo una pausa.
- Viene utilizzato un oggetto della libreria common per gestire i LED.
-
- Uno stimolo esterno rappresentato dalla pressione di un bottone
- causa il passaggio di stato.
-
- */
-
-#include <common.h>
-const byte input = 2; // PIN del bottone
-int pausa = 3000;
-enum states_available { // Stati della FMS
- turn_green, // Dinamico, transizione
- green, // Statico
- wait_button,
- turn_red,
- red
-};
-
-states_available FSM1 ;
-states_available FSM2 ;
-
-
-void setup() {
- pinMode(input, INPUT_PULLUP);
- Serial.begin(9600);
- Serial.flush();
-}
-
-RGBLed led_main(11, 10, 9);
-RGBLed led_secondary(8, 7, 6);
-
-void loop() {
-switch (FSM1) {
- case turn_green :
- led_main.Green();
- FSM1 = green ; // Setta il prossimo state
- FSM2 = red ; // Setta il prossimo state
- break;
-
- case green:
- delay(pausa * 2/3);
- FSM1 = wait_button ;
- break;
-
- case wait_button:
- if (digitalRead(input) == LOW) {
- FSM1 = turn_red ; // Il passaggio di stato avviene alla pressione di un bottone
- };
- delay(20);
- break;
-
- case turn_red :
- led_main.Yellow();
- delay(pausa/3);
- led_main.Red();
- FSM1 = red ;
- FSM2 = turn_green; // Stimolo al semafor secondario
- break;
-
- case red :
- //delay(pausa);
- //main = turn_green ;
- break;
-}
-switch (FSM2) {
- case turn_green :
- led_secondary.Green();
- FSM2 = green ; // Setta il prossimo state
- break;
-
- case green:
- delay(pausa * 2/3);
- FSM2 = turn_red ; // Niente stimoli
- break;
-
- case turn_red :
- led_secondary.Yellow();
- delay(pausa/3);
- FSM1 = turn_green ;
- FSM2 = red ;
- break;
-
- case red :
- led_secondary.Red();
- break;
-}
-
-Serial.print(millis());
-Serial.print(" \t Stato attuale Main: ");
-Serial.print(FSM1);
-Serial.print(", secondary: ");
-Serial.println(FSM2);
-
-}
--- /dev/null
+/*
+ Semaforo RGB
+
+ Un singolo semaforo costruito col paradigma delle macchine a stato.
+ Viene utilizzato un oggetto della libreria common per gestire il LED.
+
+ Uno stimolo esterno rappresentato dalla pressione di un bottone
+ causa il passaggio di stato.
+
+- Schema per un led RGB: https://lab.piffa.net/schemi/rgb.jpg
+- Schema per un bottone: https://www.arduino.cc/en/uploads/Tutorial/inputPullupButton.png
+ */
+
+#include <common.h>
+const byte input = 2; // PIN del bottone
+int pausa = 3000;
+enum states_available { // Stati della FMS
+ turn_green, // Dinamico, transizione
+ green, // Statico
+ wait_button, // Evento - Stimolo
+ turn_red, // Dinamico, transizione
+ red // Statico
+};
+
+states_available state ;
+
+
+void setup() {
+ pinMode(input, INPUT_PULLUP);
+ Serial.begin(9600);
+ Serial.flush();
+}
+
+RGBLed led(11, 10, 9); //Istanziamo un oggetto led facente parte
+ // della classe RGBLed
+
+void loop() {
+switch (state) {
+ case turn_green :
+ led.Green();
+ state = green ; // Setta il prossimo state
+ break;
+
+ case green:
+ delay(pausa * 2/3);
+ state = wait_button ;
+ break;
+
+ case wait_button:
+ if (digitalRead(input) == LOW) {
+ state = turn_red ; // Il passaggio di stato avviene alla pressione di un bottone
+ delay(20);
+ };
+
+ break;
+
+ case turn_red :
+ led.Yellow();
+ delay(pausa/3);
+ state = red ;
+ break;
+
+ case red :
+ led.Red();
+ delay(pausa);
+ state = turn_green ;
+ break;
+
+ default: // In caso di default si fa giallo lampeggiante
+ led.Yellow();
+ delay(pausa/3);
+ led.Off();
+ delay(pausa/3);
+ break;
+
+}
+Serial.print(millis());
+Serial.print(" \t Stato attuale ");
+Serial.println(state);
+
+}
+
+/* Domande:
+ 1. Introdurre una memoria nello stato green che tenga traccia della pressione del bottone per lo stato successivo.
+ 2. Introdurre un secondo semaforo che cambia stato quando viene attivato
+ lo stimolo.
+ 3. L'uso di delay() puo' essere limitativo: come rimediare?
+.
+.
+.
+.
+.
+.
+.
+.
+.
+.
+ Soluzioni
+1. Vedi sketch: semaforo_rgb
+3. Si potrebbe utilizzare un interrupt per gli stimoli oppure millis()
+ per gestire le pause.
+ */
--- /dev/null
+/*
+ Incrocio RGB
+
+ Un incrocio costituito da due strade, una principale e una secondaria.
+ La via viene concessa al secondario alla pressione di un bottone,
+ il secondario cambia automaticamente dopo una pausa.
+ Viene utilizzato un oggetto della libreria common per gestire i LED.
+
+ Uno stimolo esterno rappresentato dalla pressione di un bottone
+ causa il passaggio di stato.
+
+ Questo sketch usa due FSM indipendenti che modificano i rispettivi stati.
+
+- Schema per un led RGB: https://lab.piffa.net/schemi/rgb.jpg
+- Schema per un bottone: https://www.arduino.cc/en/uploads/Tutorial/inputPullupButton.png
+ */
+
+#include <common.h>
+const byte input = 2; // PIN del bottone
+int pausa = 3000;
+enum states_available { // Stati della FMS
+ turn_green, // Dinamico, transizione
+ green, // Statico
+ wait_button,
+ turn_red,
+ red
+};
+
+states_available FSM1 ;
+states_available FSM2 ;
+
+
+void setup() {
+ pinMode(input, INPUT_PULLUP);
+ Serial.begin(9600);
+ Serial.flush();
+}
+
+RGBLed led_main(11, 10, 9);
+RGBLed led_secondary(8, 7, 6);
+
+void loop() {
+switch (FSM1) {
+ // Semaforo principale
+ case turn_green :
+ led_main.Green();
+ FSM1 = green ; // Setta il prossimo state
+ FSM2 = red ; // Setta il prossimo state
+ break;
+
+ case green:
+ delay(pausa * 2/3);
+ FSM1 = wait_button ;
+ break;
+
+ case wait_button:
+ if (digitalRead(input) == LOW) {
+ FSM1 = turn_red ; // Il passaggio di stato avviene alla pressione di un bottone
+ };
+ delay(20);
+ break;
+
+ case turn_red :
+ led_main.Yellow();
+ delay(pausa/3);
+ led_main.Red();
+ FSM1 = red ;
+ FSM2 = turn_green; // Stimolo al semafor secondario
+ break;
+
+ case red :
+ //delay(pausa);
+ //main = turn_green ;
+ break;
+}
+
+switch (FSM2) {
+ // Semaforo Secondario
+ case turn_green :
+ led_secondary.Green();
+ FSM2 = green ; // Setta il prossimo state
+ break;
+
+ case green:
+ delay(pausa * 2/3);
+ FSM2 = turn_red ; // Niente stimoli
+ break;
+
+ case turn_red :
+ led_secondary.Yellow();
+ delay(pausa/3);
+ FSM1 = turn_green ;
+ FSM2 = red ;
+ break;
+
+ case red :
+ led_secondary.Red();
+ break;
+}
+// Debug
+Serial.print(millis());
+Serial.print(" \t Stato attuale Main: ");
+Serial.print(FSM1);
+Serial.print(", secondary: ");
+Serial.println(FSM2);
+
+}
+++ /dev/null
-/*
- Semaforo RGB
-
- Un singolo semaforo costruito col paradigma delle macchine a stato.
- Viene utilizzato un oggetto della libreria common per gestire il LED.
-
- Uno stimolo esterno rappresentato dalla pressione di un bottone
- causa il passaggio di stato.
-
- */
-
-#include <common.h>
-const byte input = 2; // PIN del bottone
-int pausa = 3000;
-enum states_available { // Stati della FMS
- turn_green, // Dinamico, transizione
- green, // Statico
- wait_button, // Evento - Stimolo
- turn_red, // Dinamico, transizione
- red // Statico
-};
-
-states_available state ;
-
-
-void setup() {
- pinMode(input, INPUT_PULLUP);
- Serial.begin(9600);
- Serial.flush();
-}
-
-RGBLed led(11, 10, 9); //Istanziamo un oggetto led facente parte
- // della classe RGBLed
-
-void loop() {
-switch (state) {
- case turn_green :
- led.Green();
- state = green ; // Setta il prossimo state
- break;
-
- case green:
- delay(pausa * 2/3);
- state = wait_button ;
- break;
-
- case wait_button:
- if (digitalRead(input) == LOW) {
- state = turn_red ; // Il passaggio di stato avviene alla pressione di un bottone
- delay(20);
- };
-
- break;
-
- case turn_red :
- led.Yellow();
- delay(pausa/3);
- led.Red();
- delay(pausa);
- state = red ;
- break;
-
- case red :
- delay(pausa);
- state = turn_green ;
- break;
-
- default: // In caso di default si fa giallo lampeggiante
- led.Yellow();
- delay(pausa/3);
- led.Off();
- delay(pausa/3);
- break;
-
-}
-Serial.print(millis());
-Serial.print(" \t Stato attuale ");
-Serial.println(state);
-
-}
-
-/* Domande:
- 1. Introdurre una memoria nello stato green che tenga traccia della pressione del bottone
- per lo stato succiessivo.
- 2. Introdurre un secondo semaforo che cambia stato quando viene attivato
- lo stimolo.
- 3. L'uso di delay() puo' essere limitativo: come rimediare?
-.
-.
-.
-.
-.
-.
-.
-.
-.
-.
- Soluzioni
-3. Si potrebbe utilizzare un interrupt per gli stimoli oppure millis()
- per gestire le pause.
- */
Implementata con millis() invece che con delay(),
sono stati aggiuntu due stati per meglio gestire lo stato yellow.
+- Schema per un led RGB: https://lab.piffa.net/schemi/rgb.jpg
+- Schema per un bottone: https://www.arduino.cc/en/uploads/Tutorial/inputPullupButton.png
*/
#include <common.h>
int pausa = 3000;
long timer ;
enum states_available { // Stati della FMS
- turn_green, // Dinamico, transizione
green, // Statico
wait_button, // Evento - Stimolo
turn_yellow, // Dinamico, transizione
void setup() {
- pinMode(input, INPUT_PULLUP);
- Serial.begin(9600);
- timer = millis();
+ pinMode(input, INPUT_PULLUP);
+ Serial.begin(9600);
+ timer = millis();
}
RGBLed led(11, 10, 9); //Istanziamo un oggetto led facente parte
- // della classe RGBLed
+// della classe RGBLed
void loop() {
switch (state) {
- case turn_green :
- state = green ; // Setta il prossimo state
- break;
- case green:
+case green:
led.Green();
if (millis() - timer >= pausa * 2/3) {
- state = wait_button ;
- timer += pausa * 2/3 ;
+ state = wait_button ;
+ timer += pausa * 2/3 ;
}
break;
- case wait_button:
- if (digitalRead(input) == LOW) {
- state = turn_yellow ; // Il passaggio di stato avviene alla pressione di un bottone
- delay(20); // Debouncing, si potrebbe fare con millis()
- timer = millis();
+case wait_button:
+ if (digitalRead(input) == LOW) {
+ state = turn_yellow ; // Il passaggio di stato avviene alla pressione di un bottone
+ delay(20); // Debouncing, si potrebbe fare con millis()
+ timer = millis();
};
break;
- case turn_yellow :
+case turn_yellow :
state = yellow ;
break;
- case yellow :
+case yellow :
led.Yellow();
- if (millis() - timer >= pausa * 2/3) {
- state = turn_red ;
- timer += pausa * 2/3;
+ if (millis() - timer >= pausa / 3) {
+ state = turn_red ;
+ timer += pausa / 3;
}
break;
- case turn_red :
+case turn_red :
state = red ;
break;
- case red :
+case red :
led.Red();
if (millis() - timer >= pausa) {
- state = turn_green ;
- timer += pausa ;
+ state = green ;
+ timer += pausa ;
}
break;
- default: // In caso di default si fa giallo lampeggiante
+default: // In caso di default si fa giallo lampeggiante
led.Yellow();
delay(pausa/3);
led.Off();
break;
}
-Serial.print(millis());
+// Debug:
+Serial.print(millis());
Serial.print(" \t Stato attuale ");
Serial.println(state);
}
/* Domande:
- 1. Introdurre un secondo semaforo che cambia stato quando viene attivato
- lo stimolo.
- 2. L'uso di delay() puo' essere limitativo: come rimediare?
+ 1. Fare in modo che nello stato verde venga recepito un'eventuale pressione
+ del bottone, venga comunque garantito un periodo minimo per il verde ma nel caso
+ sia stato premuto il bottone durante questo si passi poi direttamente al giallo.
.
.
.
.
.
Soluzioni
-2. Si potrebbe utilizzare un interrupt per gli stimoli oppure millis()
- per gestire le pause.
+1. Vedi esercizio: semaforo_rgb
*/
+++ /dev/null
-/*
- Semaforo RGB
-
-
- Doppio semaforo, una via prinicipale (led) e una secondaria (secondary):
- la via secondaria ottiene la precedenza alla pressione di un bottone.
-
- Implementata con millis() invece che con delay(),
- sono stati aggiuntu due stati per gestire lo stato yellow
- del semafor secondario.
-
- Lo sketch e' stato implementato con una sola FSM in cui si incrociano
- gli stati dei due semafori.
-
- */
-
-#include <common.h>
-const byte input = 2; // PIN del bottone
-int pausa = 3000;
-long timer ;
-enum states_available { // Stati della FMS
- turn_green, // Dinamico, transizione
- green, // Statico
- wait_button, // Evento - Stimolo
- turn_yellow, // Dinamico, transizione
- yellow, // Statico
- turn_red, // Dinamico, transizione
- turn_sec_yellow, // Yellow per semaforo secondario
- sec_yellow,
- red // Statico
-};
-
-states_available state ;
-
-
-void setup() {
- pinMode(input, INPUT_PULLUP);
- Serial.begin(9600);
- timer = millis();
-}
-
-RGBLed led(11, 10, 9); // Semaforo principale
-RGBLed secondary(8,7,6); // Semaforo secondario
-
-
-void loop() {
-switch (state) {
- case turn_green :
- led.Green();
- secondary.Red() ;
- state = green ; // Setta il prossimo state
- break;
-
- case green:
- if (millis() - timer => pausa * 2/3) {
- state = wait_button ;
- timer += pausa * 2/3 ;
- }
- break;
-
- case wait_button:
- if (digitalRead(input) == LOW) {
- delay(20); // Debouncing, si potrebbe fare con millis()
- state = turn_yellow ; // Il passaggio di stato avviene alla pressione di un bottone
- timer = millis();
- };
-
- break;
-
- case turn_yellow :
- led.Yellow();
- state = yellow ;
- break;
-
- case yellow :
- if (millis() - timer >= pausa / 3) {
- state = turn_red ;
- timer += pausa / 3;
- }
- break;
-
- case turn_red :
- led.Red();
- secondary.Green();
- state = red ;
- break;
-
- case red :
- if (millis() - timer >= pausa /3) {
- state = turn_sec_yellow ;
- timer += pausa /3 ;
- }
- break;
-
- case turn_sec_yellow :
- secondary.Yellow();
- state = sec_yellow ;
- break;
-
- case sec_yellow :
- if (millis() - timer >= pausa / 3) {
- state = turn_green ;
- timer += pausa /3;
- }
- break;
-
- default: // In caso di default si fa giallo lampeggiante
- led.Yellow();
- secondary.Yellow();
- delay(pausa/3);
- led.Off();
- secondary.Off();
- delay(pausa/3);
- break;
-
-}
-Serial.print(millis());
-Serial.print(" \t Stato attuale ");
-Serial.println(state);
-
-}
-
-/* Domande:
- 1. E' agevole inserire degli altri semafori?
- 2. Provare a inserire un altro semafori implementando una FSM
- separata.
-.
-.
-.
-.
-.
-.
-.
-.
-.
-.
- Soluzioni
-1. Be' bisogna ragionare sul loro comportamente in rapporto alla FSM principale, diciamo che non e' un approccio plug and play.
-2. Vedi esercizio successivo.
- */
--- /dev/null
+/*
+ Semaforo RGB single FSM
+
+
+ Doppio semaforo, una via prinicipale (led) e una secondaria (secondary):
+ la via secondaria ottiene la precedenza alla pressione di un bottone.
+
+ Implementata con millis() invece che con delay(),
+ sono stati aggiuntu due stati per gestire lo stato yellow
+ del semafor secondario.
+
+ Lo sketch e' stato implementato con una sola FSM in cui si incrociano
+ gli stati dei due semafori.
+
+- Schema per un led RGB: https://lab.piffa.net/schemi/rgb.jpg
+- Schema per un bottone: https://www.arduino.cc/en/uploads/Tutorial/inputPullupButton.png
+ */
+
+#include <common.h>
+const byte input = 2; // PIN del bottone
+int pausa = 3000;
+long timer ;
+enum states_available { // Stati della FMS
+ turn_green, // Dinamico, transizione
+ green, // Statico
+ wait_button, // Evento - Stimolo
+ turn_yellow, // Dinamico, transizione
+ yellow, // Statico
+ turn_red, // Dinamico, transizione
+ turn_sec_yellow, // Yellow per semaforo secondario
+ sec_yellow,
+ red // Statico
+};
+
+states_available state ;
+
+
+void setup() {
+ pinMode(input, INPUT_PULLUP);
+ Serial.begin(9600);
+ timer = millis();
+}
+
+RGBLed led(11, 10, 9); // Semaforo principale
+RGBLed secondary(8,7,6); // Semaforo secondario
+
+
+void loop() {
+switch (state) {
+ case turn_green :
+ led.Green();
+ secondary.Red() ;
+ state = green ; // Setta il prossimo state
+ break;
+
+ case green:
+ if (millis() - timer => pausa * 2/3) {
+ state = wait_button ;
+ timer += pausa * 2/3 ;
+ }
+ break;
+
+ case wait_button:
+ if (digitalRead(input) == LOW) {
+ delay(20); // Debouncing, si potrebbe fare con millis()
+ state = turn_yellow ; // Il passaggio di stato avviene alla pressione di un bottone
+ timer = millis();
+ };
+
+ break;
+
+ case turn_yellow :
+ led.Yellow();
+ state = yellow ;
+ break;
+
+ case yellow :
+ if (millis() - timer >= pausa / 3) {
+ state = turn_red ;
+ timer += pausa / 3;
+ }
+ break;
+
+ case turn_red :
+ led.Red();
+ secondary.Green();
+ state = red ;
+ break;
+
+ case red :
+ if (millis() - timer >= pausa /3) {
+ state = turn_sec_yellow ;
+ timer += pausa /3 ;
+ }
+ break;
+
+ case turn_sec_yellow :
+ secondary.Yellow();
+ state = sec_yellow ;
+ break;
+
+ case sec_yellow :
+ if (millis() - timer >= pausa / 3) {
+ state = turn_green ;
+ timer += pausa /3;
+ }
+ break;
+
+ default: // In caso di default si fa giallo lampeggiante
+ led.Yellow();
+ secondary.Yellow();
+ delay(pausa/3);
+ led.Off();
+ secondary.Off();
+ delay(pausa/3);
+ break;
+
+}
+Serial.print(millis());
+Serial.print(" \t Stato attuale ");
+Serial.println(state);
+
+}
+
+/* Domande:
+ 1. E' agevole inserire degli altri semafori?
+ 2. Provare a inserire un altro semafori implementando una FSM
+ separata.
+.
+.
+.
+.
+.
+.
+.
+.
+.
+.
+ Soluzioni
+1. Be' bisogna ragionare sul loro comportamente in rapporto alla FSM principale, diciamo che non e' un approccio plug and play.
+2. Vedi esercizio successivo.
+ */
/*
- Semaforo RGB
+ Semaforo con doppia FSM
- Un singolo semaforo costruito col paradigma delle macchine a stato.
- Viene utilizzato un oggetto della libreria common per gestire il LED.
+Due FSM indipendenti per la gestione di ognuno dei 2 semafori
+che costituiscono un incrocio. Le due FSM possono modificare
+i rispettivi stati.
- Uno stimolo esterno rappresentato dalla pressione di un bottone
- causa il passaggio di stato.
+Un singolo semaforo costruito col paradigma delle macchine a stato.
+Viene utilizzato un oggetto della libreria common per gestire il LED.
- Implementata con millis() invece che con delay(),
- sono stati aggiuntu due stati per meglio gestire lo stato yellow.
+Uno stimolo esterno rappresentato dalla pressione di un bottone
+causa il passaggio di stato.
+Implementata con millis() invece che con delay(),
+sono stati aggiuntu due stati per meglio gestire lo stato yellow.
+
+- Schema per un led RGB: https://lab.piffa.net/schemi/rgb.jpg
+- Schema per un bottone: https://www.arduino.cc/en/uploads/Tutorial/inputPullupButton.png
*/
#include <common.h>
--- /dev/null
+/*
+ Semaforo RGB
+
+Version: singolo semaforo + millis + memoria giallo
+
+ Un singolo semaforo costruito col paradigma delle macchine a stato.
+ Viene utilizzato un oggetto della libreria common per gestire il LED.
+
+ Uno stimolo esterno rappresentato dalla pressione di un bottone
+ causa il passaggio di stato.
+
+ Implementata con millis() invece che con delay(),
+ sono stati aggiuntu due stati per meglio gestire lo stato yellow.
+
+ */
+
+#include <common.h>
+const byte input = 2; // PIN del bottone
+int pausa = 3000;
+long timer ;
+enum states_available { // Stati della FMS
+ green, // Statico
+ yellow, // Statico
+ red // Statico
+};
+
+states_available state ;
+boolean wait = 0;
+
+
+void setup() {
+ pinMode(input, INPUT_PULLUP);
+ Serial.begin(9600);
+ timer = millis();
+}
+
+RGBLed led(11, 10, 9); //Istanziamo un oggetto led facente parte
+// della classe RGBLed
+
+void loop() {
+ switch (state) {
+
+ case green:
+ led.Green();
+ if (wait && (millis() - timer >= pausa * 2/3)) {
+ state = yellow;
+ timer = millis();
+ }
+
+ if (digitalRead(input) == LOW) {
+ wait = 1;
+ }
+ break;
+
+
+ case yellow :
+ led.Yellow();
+ if (millis() - timer >= pausa /3) {
+ state = red ;
+ wait = 0 ;
+ timer += pausa /3;
+ }
+ break;
+
+ case red :
+ led.Red();
+ if (millis() - timer >= pausa) {
+ state = green ;
+ timer += pausa ;
+ }
+ break;
+
+ default: // In caso di default si fa giallo lampeggiante
+ led.Yellow();
+ delay(pausa/3);
+ led.Off();
+ delay(pausa/3);
+ break;
+
+ }
+
+ //Debug:
+ Serial.print(millis());
+ Serial.print(" \t Stato attuale ");
+ Serial.print(state);
+ Serial.print(" \t Wait: ");
+ Serial.println(wait);
+
+}
+
+/* Domande:
+ 1. Introdurre un secondo semaforo che cambia stato quando viene attivato
+ lo stimolo.
+ 2. L'uso di delay() puo' essere limitativo: come rimediare?
+.
+.
+.
+.
+.
+.
+.
+.
+.
+.
+ Soluzioni
+2. Si potrebbe utilizzare un interrupt per gli stimoli oppure millis()
+ per gestire le pause.
+ */
enum states_available { // Stati della FMS
turn_green, // Dinamico, transizione
green, // Statico
- wait_button, // Evento - Stimolo
- turn_yellow, // Dinamico, transizione
yellow, // Statico
- turn_red, // Dinamico, transizione
red // Statico
};
states_available state ;
+boolean wait = 0;
void setup() {
- pinMode(input, INPUT_PULLUP);
- Serial.begin(9600);
- timer = millis();
+ pinMode(input, INPUT_PULLUP);
+ Serial.begin(9600);
+ timer = millis();
}
RGBLed led(11, 10, 9); //Istanziamo un oggetto led facente parte
- // della classe RGBLed
+// della classe RGBLed
void loop() {
-switch (state) {
+ switch (state) {
case turn_green :
- state = green ; // Setta il prossimo state
- break;
+ state = green ; // Setta il prossimo state
+ break;
case green:
- led.Green();
- if (millis() - timer >= pausa * 2/3) {
- state = wait_button ;
- timer += pausa * 2/3;
- }
- break;
+ led.Green();
+ if (wait && millis() - timer >= pausa * 2/3) {
+ state = yellow;
+ timer = millis();
+ }
- case wait_button:
- if (digitalRead(input) == LOW) {
- state = turn_yellow ; // Il passaggio di stato avviene alla pressione di un bottone
- delay(20); // Debouncing, si potrebbe fare con millis()
- timer = millis();
- };
- break;
+ if (digitalRead(input) == LOW) {
+ wait = 1;
+ }
+ break;
- case turn_yellow :
- state = yellow ;
- break;
case yellow :
- led.Yellow();
- if (millis() - timer >= pausa * 2/3) {
- state = turn_red ;
- timer += pausa * 2/3;
- }
- break;
-
- case turn_red :
- state = red ;
- break;
+ led.Yellow();
+ if (millis() - timer >= pausa /3) {
+ state = red ;
+ wait = 0 ;
+ timer += pausa /3;
+ }
+ break;
case red :
- led.Red();
- if (millis() - timer >= pausa) {
- state = turn_green ;
- timer += pausa ;
- }
- break;
+ led.Red();
+ if (millis() - timer >= pausa) {
+ state = turn_green ;
+ timer += pausa ;
+ }
+ break;
default: // In caso di default si fa giallo lampeggiante
- led.Yellow();
- delay(pausa/3);
- led.Off();
- delay(pausa/3);
- break;
+ led.Yellow();
+ delay(pausa/3);
+ led.Off();
+ delay(pausa/3);
+ break;
-}
-Serial.print(millis());
-Serial.print(" \t Stato attuale ");
-Serial.println(state);
+ }
+
+ //Debug:
+ Serial.print(millis());
+ Serial.print(" \t Stato attuale ");
+ Serial.print(state);
+ Serial.print(" \t Wait: ");
+ Serial.println(wait);
}