olelek

toy cash register

Feb 18th, 2019
261
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

Adblocker detected! Please consider disabling it...

We've detected AdBlock Plus or some other adblocking software preventing Pastebin.com from fully loading.

We don't have any obnoxious sound, or popup ads, we actively block these annoying types of ads!

Please add Pastebin.com to your ad blocker whitelist or disable your adblocking software.

×