SHARE
TWEET

toy cash register

olelek Feb 18th, 2019 (edited) 99 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /*
  2.  * Zabawkowa kasa fiskalna
  3.  * 2019-01-31 Aleksander Kawęczyński e.vt0.pl
  4.  * Arduino pro mini, klawiatura membranowa 4x4, LCD 16x2, drukarka DP-Q58A
  5.  *
  6.  * Układ na wejściu zasilania z szeregowo podłączonym mosfetem-p, załączanie: microswitch chwilowy, podtrzymanie włączenia przez pin A3.
  7.  *
  8.  * 13 - power control: high - on, low - off; connected to gate of transistor, pobór prądu w stanie wyłączonym: 0,1uA
  9.  * 2 - printer software serial
  10.  * 3 .. 10 - 4x4 keyboard matrix
  11.  * 11 - LCD RS (4)
  12.  * 12 - LCD E (6)
  13.  * A0 - LCD D4 (11)
  14.  * A1 - LCD D5 (12)
  15.  * A2 - LCD D6 (13)
  16.  * A3 - LCD D7 (14)
  17.  * A6 - Vbat przez dzielnik 100K/100K
  18.  */
  19. #include <LiquidCrystal.h>
  20. #include <SendOnlySoftwareSerial.h>
  21. #include <EEPROM.h>
  22. #include <avr/pgmspace.h>
  23.  
  24. #define POWER_CTL 13
  25. #define VBATMIN 6000   //minimum battery voltage in mV
  26. #define VERSION "1.1"
  27.  
  28. SendOnlySoftwareSerial drukarka(2);  // Tx pin
  29. LiquidCrystal lcd(11, 12, A0, A1, A2, A3);
  30.  
  31. unsigned long lastAction=0;
  32. const unsigned long idle=(5UL*60UL*1000UL); //2 minutes
  33. uint16_t keyState=0, lastKeyState=0;
  34. char buff[80];
  35. uint16_t suma_cen = 0, powerCounter = 0, printCounter = 0;
  36. const uint8_t baza = 5;
  37. uint8_t cashier=0;
  38.  
  39. const char  s0[] PROGMEM = "BU\x02KA";
  40. const char  s1[] PROGMEM = "SER";
  41. const char  s2[] PROGMEM = "MLEKO";
  42. const char  s3[] PROGMEM = "P\x02\ATKI";
  43. const char  s4[] PROGMEM = "ZESZYT";
  44. const char  s5[] PROGMEM = "LODY";
  45. const char  s6[] PROGMEM = "PIZZA";
  46. const char  s7[] PROGMEM = "WARZYWA";
  47. const char  s8[] PROGMEM = "SOK";
  48. const char  s9[] PROGMEM = "S\x02\ODYCZE";
  49. const char  s10[] PROGMEM = "KAKAO";
  50. const char  s11[] PROGMEM = "CZYTANKA";
  51.  
  52. PGM_P const produkty[] PROGMEM = {s0,s1,s2,s3,s4,s5,s6,s7,s8,s9,s10,s11};
  53.  
  54. const char  t0[] PROGMEM = " Sklep \"Julka\"";
  55. const char  t1[] PROGMEM = " Sklep \"Franek\"";
  56. const char  t2[] PROGMEM = " Sklep \"Maja\"";
  57. const char  t3[] PROGMEM = "Z A P R A S Z A";
  58. const char  t4[] PROGMEM = " DO ZOBACZENIA!";
  59.  
  60.  
  61. PGM_P const powitania[] PROGMEM = {t0,t1,t2,t3,t4};
  62.  
  63. const uint16_t ceny[] PROGMEM = {
  64.   1,//0
  65.   6,//1
  66.   3,//2
  67.   4,//3
  68.   2,//4
  69.   2,//5
  70.   10,//6
  71.   7,//7
  72.   5,//8
  73.   8,//9
  74.   9,//10
  75.   20//11
  76. };
  77.  
  78. byte el[8] = {
  79.   0b01000,
  80.   0b01001,
  81.   0b01010,
  82.   0b01100,
  83.   0b01000,
  84.   0b11000,
  85.   0b01111,
  86.   0b00000
  87. };
  88.  
  89. void setup() {
  90.   // pin configuration
  91.   pinMode(POWER_CTL, OUTPUT);
  92.   digitalWrite(POWER_CTL, HIGH);
  93.  
  94.   //licznik uruchomien
  95.  
  96.   powerCounter = EEPROM.read(0);
  97.   powerCounter += (EEPROM.read(1) << 8);
  98.   printCounter = EEPROM.read(2);
  99.   printCounter += (EEPROM.read(3) << 8);
  100.  
  101.  
  102.   if( (printCounter == 255) && (analogRead(A6)<5)){
  103.   //po przeprogramowaniu, trzeba wyczyścić zmienne  
  104.     powerCounter =0;
  105.     printCounter = 0;
  106.     EEPROM.write(2, ++printCounter);
  107.   }
  108.  
  109.   ++powerCounter;
  110.   EEPROM.write(0, powerCounter);
  111.  
  112.   lcd.begin(16, 2);
  113.   lcd.createChar(2, el);
  114.   lcd.clear();
  115.   cashier = (powerCounter % 3);
  116.   strcpy_P(buff, (PGM_P)pgm_read_word(&(powitania[cashier])));
  117.   lcd.print(buff);
  118.   lcd.setCursor(0, 1);
  119.   strcpy_P(buff, (PGM_P)pgm_read_word(&(powitania[3])));
  120.   lcd.print(buff);
  121.   drukarka.begin(9600);
  122.   //wait until power button is not pressed
  123.  
  124.   delay(100);
  125.   drukarka.print("\x1B\x40\x1B\x61\x49");
  126.   lastAction = millis();
  127. }
  128.  
  129. void loop() {
  130.   //Keyboard module:
  131.   uint16_t keys = keyDown();
  132.   uint8_t wybranyProdukt = 0;
  133.   //logic module
  134.   if(keys) lastAction = millis();
  135.  
  136.   //battery voltage check
  137.  
  138.  
  139.   switch (keys){
  140.     case 0:
  141.       delay(100);
  142.       if((analogRead(A6)*10) < VBATMIN){
  143.       lcd.clear();
  144.       lcd.print("Bateria");
  145.       lcd.setCursor(0, 1);
  146.       lcd.print("Roz\x02adowana!");
  147.       delay(2000);
  148.       wylacz();
  149.       }
  150.     break;
  151.     case (1<<0)://D -- zakonczenie paragonu
  152.       if(suma_cen == 0){
  153.         lcd.clear();
  154.         sprintf(buff, "Vb=%d mV; v" VERSION,analogRead(A6)*10 );
  155.         lcd.print(buff);
  156.         lcd.setCursor(0, 1);
  157.         sprintf(buff, "PWc=%d PrC=%d",powerCounter, printCounter);
  158.         lcd.print(buff);
  159.         delay(2000);
  160.         lcd_powitanie();
  161.       }
  162.       else{
  163.         printFooter();
  164.       }
  165.  
  166.      
  167.     break;
  168.     case (1<<1)://#
  169.       wybranyProdukt = 12;
  170.     break;
  171.     case (1<<2)://0
  172.       wybranyProdukt = 10;
  173.     break;
  174.     case (1<<3)://*
  175.       wybranyProdukt = 11;
  176.     break;
  177.     case (1<<4)://C
  178.       //change cashier
  179.         if(suma_cen == 0){
  180.           cashier = (++cashier) % 3;
  181.           lcd_powitanie();
  182.         }
  183.     break;
  184.     case (1<<5)://9
  185.       wybranyProdukt = 9;
  186.     break;
  187.     case (1<<6)://8
  188.       wybranyProdukt = 8;
  189.     break;
  190.     case (1<<7)://7
  191.       wybranyProdukt = 7;
  192.     break;
  193.     case (1<<8)://B
  194.       if(suma_cen == 0){
  195.         //wydrukuj cos innego
  196.         drukarka.print("\x1B\x61\x48"); //alignment left
  197.        
  198.         drukarka.print("       ,~~.\r\
  199.      (  6 )-_,\r\
  200. ('\___ )=='-'    KACZKA\r\
  201.  \\ .   ) )\r\
  202.   \\ `-' /    \r\
  203. ~'`~'`~'`~'`~\r\r\r");
  204.  
  205.         drukarka.print("\x1B\x61\x49"); //alignment middle
  206.       }
  207.      
  208.     break;
  209.     case (1<<9)://6
  210.       wybranyProdukt = 6;
  211.     break;
  212.     case (1<<10)://5
  213.       wybranyProdukt = 5;
  214.     break;
  215.     case (1<<11)://4
  216.       wybranyProdukt = 4;
  217.     break;
  218.     case (1<<12)://A
  219.       if(suma_cen > 0)
  220.         printFooter(); //zakoncz paragon przed wylaczeniem
  221.        
  222.       wylacz();
  223.        
  224.     break;
  225.     case (1<<13)://3
  226.       wybranyProdukt = 3;
  227.     break;
  228.     case (1<<14)://2
  229.       wybranyProdukt = 2;
  230.     break;
  231.     case (1<<15)://1
  232.       wybranyProdukt = 1;
  233.     break;
  234.   }
  235.  
  236.   if(wybranyProdukt){
  237.     int isFirst=0;
  238.     if(suma_cen == 0) isFirst=1;//pierwszy produkt na tym paragonie,
  239.      
  240.    
  241.      strcpy_P(buff, (PGM_P)pgm_read_word(&(produkty[wybranyProdukt-1])));
  242.     uint8_t a = strlen(buff);
  243.     uint16_t cena = pgm_read_word(&(ceny[wybranyProdukt-1]));
  244.     suma_cen += cena;
  245.     lcd.clear();
  246.     lcd.print(buff);
  247.     itoa(cena, buff, 10);
  248.     lcd.setCursor(15-2-strlen(buff), 0);
  249.     lcd.print(buff);
  250.     lcd.print(" Z\x02");
  251.    
  252.     lcd.setCursor(0, 1);
  253.     sprintf(buff, "SUMA: %7d Z\x02",suma_cen);
  254.     lcd.print(buff);
  255.     ;
  256.    
  257.     if(isFirst) {
  258.       printHeader();
  259.       isFirst=0;
  260.       }
  261.     //drukowanie pozycji na paragonie
  262.     strcpy_P(buff, (PGM_P)pgm_read_word(&(produkty[wybranyProdukt-1])));
  263.     //zamiana \x02 na \x9D
  264.     for (char* p = buff; p = strchr(p, 0x02); ++p) {
  265.       *p = 0x9D;
  266.     }
  267.     drukarka.print(buff);
  268.     int spacje = 32-7-a;
  269.     for(uint8_t k=0;k<spacje;++k){drukarka.print(" ");}
  270.     sprintf(buff, "%4d Z\x9D\r", cena);
  271.     drukarka.print(buff);
  272.     delay(500);
  273.    
  274.     wybranyProdukt = 0;
  275.    
  276.   }
  277.    
  278.   //test odczytu klawiatury
  279.   /*
  280.   lcd.clear();
  281.   lcd16Bit(keys);
  282.   lcd.setCursor(0, 1);
  283.   lcd16Bit(keyState);
  284.   */
  285.  
  286.  
  287.   //test odczytu z pamieci FLASH i wyswietlania
  288.   /*
  289.   for (unsigned char i = 0; i < baza; i++)
  290.   {
  291.    
  292.     delay(1000);
  293.   }
  294.   */
  295.  
  296.   powerFunction();
  297.   delay(10);
  298.  
  299. }
  300.  
  301. uint16_t getKeyState(){
  302.   //3 .. 10 - 4x4 keyboard matrix
  303.   uint16_t reads=0;
  304.   pinMode(3, INPUT_PULLUP);
  305.   pinMode(4, INPUT_PULLUP);
  306.   pinMode(5, INPUT_PULLUP);
  307.   pinMode(6, INPUT_PULLUP);
  308.   pinMode(7, INPUT);
  309.   pinMode(8, INPUT);
  310.   pinMode(9, INPUT);
  311.   pinMode(10, INPUT);
  312.   digitalWrite(7, LOW);
  313.   digitalWrite(8, LOW);
  314.   digitalWrite(9, LOW);
  315.   digitalWrite(10, LOW);
  316.  
  317.  
  318.   //col A
  319.   pinMode(7, OUTPUT);
  320.   delay(1);
  321.   reads += (((PIND & 0x78)>>3) << 0);
  322.   pinMode(7, INPUT);
  323.   //col B
  324.   pinMode(8, OUTPUT);
  325.   delay(1);
  326.   reads += (((PIND & 0x78)>>3) << 4);
  327.   pinMode(8, INPUT);
  328.   //col C
  329.   pinMode(9, OUTPUT);
  330.   delay(1);
  331.   reads += (((PIND & 0x78)>>3) << 8);
  332.   pinMode(9, INPUT);
  333.   //col D
  334.   pinMode(10, OUTPUT);
  335.   delay(1);
  336.   reads += (((PIND & 0x78)>>3) << 12);
  337.   pinMode(10, INPUT);
  338.  
  339.  
  340.   return ~reads;
  341. }
  342.  
  343. void lcd_powitanie()
  344. {
  345.   lcd.clear();
  346.   strcpy_P(buff, (PGM_P)pgm_read_word(&(powitania[cashier])));
  347.   lcd.print(buff);
  348.   lcd.setCursor(0, 1);
  349.   strcpy_P(buff, (PGM_P)pgm_read_word(&(powitania[3])));
  350.   lcd.print(buff);  
  351. }
  352.  
  353.  
  354. void lcd16Bit(uint16_t number)
  355. {
  356.   for (uint8_t i=0;i<16;i++)
  357.   {
  358.     if (((number >> (15-i)) & 0x01))
  359.     {
  360.       lcd.print("1");
  361.     }
  362.     else
  363.     {
  364.       lcd.print("0");
  365.     }
  366.    
  367.   }
  368. }
  369.  
  370.  
  371. ///drukuje nagłówek paragonu
  372. void printHeader(){
  373.   EEPROM.write(2, ++printCounter);
  374.   strcpy_P(buff, (PGM_P)pgm_read_word(&(powitania[cashier])));
  375.   drukarka.print("\x1B\x61\x49"); //alignment middle
  376.   drukarka.print("\x1B\x45\x01"); //bold print
  377.   drukarka.print("\x1B\x0E\x02"); //times 2 wider pattern
  378.   drukarka.print(buff);
  379.   drukarka.print("\x1B\x45\x00"); //bold print off
  380.   drukarka.print("\x1B\x14\x02"); //cancel times wider pattern
  381.   delay(30);
  382.   sprintf(buff, "DZIEN DOBRY! \r\nPARAGON NR %d\r\n\x1D\x6B\x03",printCounter);
  383.   drukarka.print(buff);
  384.   sprintf(buff,"%08d", printCounter);
  385.   drukarka.write((uint8_t)0);
  386.   sprintf(buff, "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\r",printCounter);
  387.   drukarka.print(buff);
  388.   //delay(2000);
  389. }
  390.  
  391. void printFooter(){
  392.   lcd.clear();
  393.   lcd.print("Drukowanie ...");
  394.   lcd.setCursor(0, 1);
  395.   sprintf(buff, "SUMA: %7d Z\x02",suma_cen);
  396.   lcd.print(buff);
  397.   sprintf(buff, "\x1B\x61\x50+ \r\x1B\x61\x49================================\r\n");
  398.   drukarka.print(buff);
  399.   delay(100);
  400.   sprintf(buff, "RAZEM:%23d Z\x9D\r\rDO WIDZENIA!\r\r\r\r",suma_cen);
  401.   drukarka.print(buff);
  402.   delay(100);
  403.   suma_cen = 0;
  404.  
  405.   lcd_powitanie();
  406.  
  407.   }
  408.  
  409. uint16_t keyDown(){
  410.   uint16_t ret;
  411.   lastKeyState = keyState;
  412.   keyState = getKeyState();
  413.   ret = ((keyState^lastKeyState)&keyState);
  414.   return ret;  
  415.  
  416. }
  417.  
  418. void powerFunction(){
  419.    //Power function:
  420.   unsigned long czas = millis();
  421.   if((lastAction+idle) < czas )
  422.     wylacz();
  423.  
  424.   //actions:
  425.   //lastAction = millis();
  426.  
  427. }
  428.  
  429. void wylacz(){
  430.   lcd.clear();
  431.   strcpy_P(buff, (PGM_P)pgm_read_word(&(powitania[(powerCounter % 3)])));
  432.   lcd.print(buff);
  433.   lcd.setCursor(0, 1);
  434.   strcpy_P(buff, (PGM_P)pgm_read_word(&(powitania[4])));
  435.   lcd.print(buff);
  436.   delay(2000);
  437.   lcd.clear();
  438.   digitalWrite(POWER_CTL, LOW);
  439.   for(;;){};
  440. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
Not a member of Pastebin yet?
Sign Up, it unlocks many cool features!
 
Top