FSM reorder
authorAndrea Manni <andrea@piffa.net>
Thu, 9 Mar 2017 11:54:22 +0000 (12:54 +0100)
committerAndrea Manni <andrea@piffa.net>
Thu, 9 Mar 2017 16:27:39 +0000 (17:27 +0100)
16 files changed:
advanced_projects/state_machine/README
advanced_projects/state_machine/README.html [new file with mode: 0644]
advanced_projects/state_machine/blink/blink_1/blink_1.ino [deleted file]
advanced_projects/state_machine/blink/blink_2_trans/blink_2_trans.ino [deleted file]
advanced_projects/state_machine/blink_2_trans/blink_2_trans.ino
advanced_projects/state_machine/semaforo_1/semaforo_1.ino
advanced_projects/state_machine/semaforo_2_1_doppio/semaforo_2_1_doppio.ino [deleted file]
advanced_projects/state_machine/semaforo_2_1_stimolo/semaforo_2_1_stimolo.ino [new file with mode: 0644]
advanced_projects/state_machine/semaforo_2_2_doppio/semaforo_2_2_doppio.ino [new file with mode: 0644]
advanced_projects/state_machine/semaforo_2_stimolo/semaforo_2_stimolo.ino [deleted file]
advanced_projects/state_machine/semaforo_3_millis/semaforo_3_millis.ino
advanced_projects/state_machine/semaforo_4_doppio/semaforo_4_doppio.ino [deleted file]
advanced_projects/state_machine/semaforo_4_doppio_single_FSM/semaforo_4_doppio_single_FSM.ino [new file with mode: 0644]
advanced_projects/state_machine/semaforo_5_doppia_fsm/semaforo_5_doppia_fsm.ino
advanced_projects/state_machine/semaforo_rgb/semaforo_rgb.ino [new file with mode: 0644]
advanced_projects/state_machine/semaforo_rgb_stimolo_millis/semaforo_rgb_stimolo_millis.ino

index 15f5175..d17dce6 100644 (file)
@@ -4,14 +4,33 @@ FSM
 
 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/
 
 
 
@@ -21,3 +40,4 @@ Elementi
 
 * http://playground.arduino.cc/Code/Enum
 * https://www.arduino.cc/en/Reference/SwitchCase
+* https://learn.adafruit.com/multi-tasking-the-arduino-part-1
diff --git a/advanced_projects/state_machine/README.html b/advanced_projects/state_machine/README.html
new file mode 100644 (file)
index 0000000..fe1f325
--- /dev/null
@@ -0,0 +1,605 @@
+<!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 &quot;Luci per Aerei RC&quot;:
+- <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>
diff --git a/advanced_projects/state_machine/blink/blink_1/blink_1.ino b/advanced_projects/state_machine/blink/blink_1/blink_1.ino
deleted file mode 100644 (file)
index c119794..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
-  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;
-    }
-}
diff --git a/advanced_projects/state_machine/blink/blink_2_trans/blink_2_trans.ino b/advanced_projects/state_machine/blink/blink_2_trans/blink_2_trans.ino
deleted file mode 100644 (file)
index 1841f87..0000000
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
-  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
-*/
index 4abe599..6545cde 100644 (file)
@@ -4,7 +4,7 @@
   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:
 
  */
 
@@ -18,14 +18,13 @@ void setup() {
     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) {
index 1318a08..b32e637 100644 (file)
@@ -4,6 +4,9 @@
    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;
@@ -14,7 +17,7 @@ enum states_available { // Stati della FMS
     red
 };
 
-states_available state  ;
+states_available state = red;
 
 
 void setup() {
@@ -39,13 +42,12 @@ switch (state) {
 
     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;
diff --git a/advanced_projects/state_machine/semaforo_2_1_doppio/semaforo_2_1_doppio.ino b/advanced_projects/state_machine/semaforo_2_1_doppio/semaforo_2_1_doppio.ino
deleted file mode 100644 (file)
index 412e11f..0000000
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
-   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);
-
-}
diff --git a/advanced_projects/state_machine/semaforo_2_1_stimolo/semaforo_2_1_stimolo.ino b/advanced_projects/state_machine/semaforo_2_1_stimolo/semaforo_2_1_stimolo.ino
new file mode 100644 (file)
index 0000000..b151838
--- /dev/null
@@ -0,0 +1,102 @@
+/*
+   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.
+ */
diff --git a/advanced_projects/state_machine/semaforo_2_2_doppio/semaforo_2_2_doppio.ino b/advanced_projects/state_machine/semaforo_2_2_doppio/semaforo_2_2_doppio.ino
new file mode 100644 (file)
index 0000000..e25b487
--- /dev/null
@@ -0,0 +1,107 @@
+/*
+   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);
+
+}
diff --git a/advanced_projects/state_machine/semaforo_2_stimolo/semaforo_2_stimolo.ino b/advanced_projects/state_machine/semaforo_2_stimolo/semaforo_2_stimolo.ino
deleted file mode 100644 (file)
index 9b4b367..0000000
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
-   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.
- */
index 68825a6..4cc7dcb 100644 (file)
@@ -10,6 +10,8 @@
    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>
@@ -17,7 +19,6 @@ 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
@@ -30,61 +31,58 @@ states_available state  ;
 
 
 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();
@@ -92,16 +90,17 @@ switch (state) {
     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.
 .
 .
 .
@@ -113,6 +112,5 @@ Serial.println(state);
 .
 .
   Soluzioni
-2. Si potrebbe utilizzare un interrupt per gli stimoli oppure millis()
-   per gestire le pause.
+1. Vedi esercizio: semaforo_rgb
  */
diff --git a/advanced_projects/state_machine/semaforo_4_doppio/semaforo_4_doppio.ino b/advanced_projects/state_machine/semaforo_4_doppio/semaforo_4_doppio.ino
deleted file mode 100644 (file)
index ab22ae0..0000000
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
-   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.
- */
diff --git a/advanced_projects/state_machine/semaforo_4_doppio_single_FSM/semaforo_4_doppio_single_FSM.ino b/advanced_projects/state_machine/semaforo_4_doppio_single_FSM/semaforo_4_doppio_single_FSM.ino
new file mode 100644 (file)
index 0000000..be9bb04
--- /dev/null
@@ -0,0 +1,142 @@
+/*
+   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.
+ */
index dfcc362..db72e6a 100644 (file)
@@ -1,15 +1,21 @@
 /*
-   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>
diff --git a/advanced_projects/state_machine/semaforo_rgb/semaforo_rgb.ino b/advanced_projects/state_machine/semaforo_rgb/semaforo_rgb.ino
new file mode 100644 (file)
index 0000000..3260dbb
--- /dev/null
@@ -0,0 +1,108 @@
+/*
+   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.
+ */
index a8a14c0..093879b 100644 (file)
@@ -19,82 +19,74 @@ 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
     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);
 
 }