Advertisement
Stelios_Gakis

Machine

Jan 8th, 2019
84
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.72 KB | None | 0 0
  1. typedef void State;//statefunctions should be of this type
  2. //macro to call runstate member fuction by runstate function pointer
  3. #define EXEC(object) ((object).*(object.Exec))()
  4. class SM;
  5.  
  6. //save som time by reading variable directly
  7. extern volatile unsigned long timer0_millis;
  8.  
  9. typedef void State;//statefunctions should be of this type
  10. typedef State (*Pstate)();//pointer to statefunction
  11.  
  12. class SM{
  13. typedef void(SM::*PRun)();//defines runstate pointer
  14.   public:
  15.     SM(Pstate);//constructor simple SM
  16.     SM(Pstate, Pstate);//constructor machine with head and body state
  17.     PRun Exec;//runstate pointer
  18.     void Set(Pstate);//simple statechange
  19.     void Set(Pstate, Pstate);//statechange to head and body state
  20.     void Finish();//suspend mschine execution
  21.     boolean Finished;//flag suspended machine
  22.   void *data;//generic data pointer
  23.     void Restart();//resume from suspension with last known states
  24.     unsigned long Statetime(){//return ms since entry, inline for efficiency
  25.       return timer0_millis - Mark;
  26.     };//Statetime();
  27.     boolean Timeout(unsigned long T){//returns true if Statetime > T
  28.       return (timer0_millis - Mark)>T;
  29.     };//Timeout()
  30.   private:
  31.     Pstate Head;//pointer to head state function
  32.     Pstate Body;//pointer to body state function
  33.     void Run(){//runstate running
  34.       Body();
  35.     };//Run()
  36.     void FRun(){//runstate entry
  37.       Mark = timer0_millis;//reset timer on entry
  38.       Head();//call head state function
  39.       Exec = &SM::Run;//set runstate to running
  40.     };//FRun()
  41.     void Idle();//runstate finished
  42.     unsigned long Mark;//timer mark
  43. };
  44.  
  45. //
  46. //
  47. //
  48. //
  49. //
  50. //
  51. //
  52. //
  53. //
  54. //
  55.  
  56. SM::SM(Pstate Initial){//create simple SM
  57.   Set(Initial);//set initial state
  58. };//constructor
  59.  
  60. //create SM with initial head and body states
  61. SM::SM(Pstate First, Pstate Rest){
  62.   Set(First, Rest);//set initial head and body state functions
  63. }//constructor
  64.  
  65. void SM::Set(Pstate Current){
  66.   Finished = false;//clear flag, just in case
  67.   Body = Current;//common head-
  68.   Head = Current;//-and body state function
  69.   Exec = &SM::FRun;//set runstate to entry
  70. };//Set()
  71.  
  72. void SM::Set(Pstate First, Pstate Rest){
  73.   Finished = false;//clear flag just in case
  74.   Head = First;//separate head-
  75.   Body = Rest;//-and body state functions
  76.   Exec =&SM::FRun;//set runstate to entry
  77. };//set()
  78.  
  79. void SM::Finish(){
  80.   Exec = &SM::Idle;//set runstate to finished
  81.   Finished = true;//set flag
  82. };//Finish()
  83.  
  84. void SM::Restart(){
  85.   Exec = &SM::FRun;//set runstate to entry
  86.   Finished = false;//clear flag
  87. }//restart
  88.  
  89. void SM::Idle(){
  90.   return;//do abolutely nothing
  91. };//Idle()
  92.  
  93. //
  94. //
  95. //
  96. //
  97. //
  98. //
  99. //
  100. //
  101. //
  102. //
  103. //
  104. //
  105. //
  106. //
  107. //
  108.  
  109. #include <LiquidCrystal.h>
  110.  
  111. #define fiveButton 2
  112. #define tenButton 3
  113. // TODO do this 4 instead for soda
  114. #define sodaButton 12
  115. #define beerButton A5
  116. #define wineButton A4
  117. #define resetButton A3
  118.  
  119. LiquidCrystal lcd(4, 5, 8, 9, 10, 11); // Parameters: (rs, enable, d4, d5, d6, d7)
  120. //LiquidCrystal lcd(6, 7, 8, 9, 10, 11); // Parameters: (rs, enable, d4, d5, d6, d7)
  121.  
  122. volatile long money;
  123. State Input();
  124. SM Machine(Input);
  125.  
  126. State FiveCrowns() {
  127.   money += 5;
  128.   updateMoney();
  129.   Machine.Set(Input);
  130. }
  131.  
  132. State TenCrowns() {
  133.   money += 10;
  134.   updateMoney();
  135.   Machine.Set(Input);
  136. }
  137.  
  138. State Soda() {
  139.   lcd.clear();
  140.   if (money < 5){
  141.     noMoney(5);
  142.   } else {
  143.     lcd.print("Giving Soda");
  144.     loadingSequence();
  145.     money -= 5;
  146.     lcd.setCursor(0,1);
  147.     lcd.clear();
  148.     lcd.print("Enjoy your Soda");
  149.     delay(1000);
  150.   }
  151.   Machine.Set(Input);
  152. }
  153.  
  154. State Beer() {
  155.   lcd.clear();
  156.   if (money < 10){
  157.     noMoney(10);
  158.   } else {
  159.     lcd.print("Giving Beer");
  160.     loadingSequence();
  161.     money -= 10;
  162.     lcd.setCursor(0,1);
  163.     lcd.clear();
  164.     lcd.print("Enjoy your Beer");
  165.     delay(1000);
  166.   }
  167.   Machine.Set(Input);
  168. }
  169.  
  170. State Wine() {
  171.   lcd.clear();
  172.   if (money < 15){
  173.     noMoney(15);
  174.   } else {
  175.     lcd.print("Giving Wine");
  176.     loadingSequence();
  177.     money -= 15;
  178.     lcd.setCursor(0,1);
  179.     lcd.clear();
  180.     lcd.print("Enjoy your Beer");
  181.     delay(1000);
  182.   }
  183.   Machine.Set(Input);
  184. }
  185.  
  186. State Reset() {
  187.   lcd.clear();
  188.   lcd.print("Now returning");
  189.   lcd.setCursor(0, 1);
  190.   lcd.print(money);
  191.   lcd.print(" SEK");
  192.   loadingSequence();
  193.   lcd.setCursor(1,12);
  194.   lcd.print("DONE");
  195.   delay(500);
  196.   lcd.clear();
  197.   lcd.print("Money returned");
  198.   lcd.setCursor(0, 1);
  199.   lcd.print("Have a nice day!");
  200.   delay(1000);
  201.   Machine.Set(Input);
  202. }
  203.  
  204. State Input() {
  205.   lcd.clear();
  206.   lcd.print("Welcome!");
  207.   updateMoney();
  208.   if (digitalRead(fiveButton)) {
  209.     Machine.Set(FiveCrowns);
  210.   } else if (digitalRead(tenButton)) {
  211.     Machine.Set(TenCrowns);
  212.   } else if (digitalRead(sodaButton)) {
  213.     Machine.Set(Soda);
  214.   } else if (digitalRead(beerButton)) {
  215.     Machine.Set(Beer);
  216.   } else if (digitalRead(wineButton)) {
  217.     Machine.Set(Wine);
  218.   } else if (digitalRead(resetButton)) {
  219.     Machine.Set(Reset);
  220.   }
  221. }
  222.  
  223. void updateMoney() {
  224.   lcd.setCursor(0, 1);
  225.   lcd.print("Money: ");
  226.   lcd.print(money);
  227.   lcd.print(" SEK");
  228.   lcd.setCursor(0, 0);
  229. }
  230.  
  231. void noMoney(int no) {
  232.   lcd.print("No money.");
  233.   lcd.setCursor(0,1);
  234.   lcd.print("Have/Need");
  235.   lcd.print(" ");
  236.   lcd.print(money);
  237.   lcd.print("/");
  238.   lcd.print(no);
  239. }
  240.  
  241. void loadingSequence(){
  242.   lcd.setCursor(1, 15);
  243.   lcd.print("%");
  244.   for (int i = 0; i < 101; i++){
  245.     lcd.setCursor(1, 13);
  246.     lcd.print(i);
  247.   }
  248. }
  249.  
  250. void setup() {
  251.   pinMode(6, OUTPUT); // Contrast pwm pin
  252.   pinMode(buzzPin, OUTPUT); //TODO use buzzPin for objects too close, also make sound play.
  253.   //TCCR2B = TCCR2B & 0b11111000 | 0b110;
  254.   analogWrite(6, 100);
  255.  
  256.   money = 0;
  257.   lcd.begin(16, 2);
  258.   Serial.begin(9600);
  259. }
  260.  
  261. void loop() {
  262.   EXEC(Machine);
  263. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement