Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- * Zabawkowa kasa fiskalna
- * 2019-01-31 Aleksander Kawęczyński e.vt0.pl
- * Arduino pro mini, klawiatura membranowa 4x4, LCD 16x2, drukarka DP-Q58A
- *
- * Układ na wejściu zasilania z szeregowo podłączonym mosfetem-p, załączanie: microswitch chwilowy, podtrzymanie włączenia przez pin A3.
- *
- * 13 - power control: high - on, low - off; connected to gate of transistor, pobór prądu w stanie wyłączonym: 0,1uA
- * 2 - printer software serial
- * 3 .. 10 - 4x4 keyboard matrix
- * 11 - LCD RS (4)
- * 12 - LCD E (6)
- * A0 - LCD D4 (11)
- * A1 - LCD D5 (12)
- * A2 - LCD D6 (13)
- * A3 - LCD D7 (14)
- * A6 - Vbat przez dzielnik 100K/100K
- */
- #include <LiquidCrystal.h>
- #include <SendOnlySoftwareSerial.h>
- #include <EEPROM.h>
- #include <avr/pgmspace.h>
- #define POWER_CTL 13
- #define VBATMIN 6000 //minimum battery voltage in mV
- #define VERSION "1.1"
- SendOnlySoftwareSerial drukarka(2); // Tx pin
- LiquidCrystal lcd(11, 12, A0, A1, A2, A3);
- unsigned long lastAction=0;
- const unsigned long idle=(5UL*60UL*1000UL); //2 minutes
- uint16_t keyState=0, lastKeyState=0;
- char buff[80];
- uint16_t suma_cen = 0, powerCounter = 0, printCounter = 0;
- const uint8_t baza = 5;
- uint8_t cashier=0;
- const char s0[] PROGMEM = "BU\x02KA";
- const char s1[] PROGMEM = "SER";
- const char s2[] PROGMEM = "MLEKO";
- const char s3[] PROGMEM = "P\x02\ATKI";
- const char s4[] PROGMEM = "ZESZYT";
- const char s5[] PROGMEM = "LODY";
- const char s6[] PROGMEM = "PIZZA";
- const char s7[] PROGMEM = "WARZYWA";
- const char s8[] PROGMEM = "SOK";
- const char s9[] PROGMEM = "S\x02\ODYCZE";
- const char s10[] PROGMEM = "KAKAO";
- const char s11[] PROGMEM = "CZYTANKA";
- PGM_P const produkty[] PROGMEM = {s0,s1,s2,s3,s4,s5,s6,s7,s8,s9,s10,s11};
- const char t0[] PROGMEM = " Sklep \"Julka\"";
- const char t1[] PROGMEM = " Sklep \"Franek\"";
- const char t2[] PROGMEM = " Sklep \"Maja\"";
- const char t3[] PROGMEM = "Z A P R A S Z A";
- const char t4[] PROGMEM = " DO ZOBACZENIA!";
- PGM_P const powitania[] PROGMEM = {t0,t1,t2,t3,t4};
- const uint16_t ceny[] PROGMEM = {
- 1,//0
- 6,//1
- 3,//2
- 4,//3
- 2,//4
- 2,//5
- 10,//6
- 7,//7
- 5,//8
- 8,//9
- 9,//10
- 20//11
- };
- byte el[8] = {
- 0b01000,
- 0b01001,
- 0b01010,
- 0b01100,
- 0b01000,
- 0b11000,
- 0b01111,
- 0b00000
- };
- void setup() {
- // pin configuration
- pinMode(POWER_CTL, OUTPUT);
- digitalWrite(POWER_CTL, HIGH);
- //licznik uruchomien
- powerCounter = EEPROM.read(0);
- powerCounter += (EEPROM.read(1) << 8);
- printCounter = EEPROM.read(2);
- printCounter += (EEPROM.read(3) << 8);
- if( (printCounter == 255) && (analogRead(A6)<5)){
- //po przeprogramowaniu, trzeba wyczyścić zmienne
- powerCounter =0;
- printCounter = 0;
- EEPROM.write(2, ++printCounter);
- }
- ++powerCounter;
- EEPROM.write(0, powerCounter);
- lcd.begin(16, 2);
- lcd.createChar(2, el);
- lcd.clear();
- cashier = (powerCounter % 3);
- strcpy_P(buff, (PGM_P)pgm_read_word(&(powitania[cashier])));
- lcd.print(buff);
- lcd.setCursor(0, 1);
- strcpy_P(buff, (PGM_P)pgm_read_word(&(powitania[3])));
- lcd.print(buff);
- drukarka.begin(9600);
- //wait until power button is not pressed
- delay(100);
- drukarka.print("\x1B\x40\x1B\x61\x49");
- lastAction = millis();
- }
- void loop() {
- //Keyboard module:
- uint16_t keys = keyDown();
- uint8_t wybranyProdukt = 0;
- //logic module
- if(keys) lastAction = millis();
- //battery voltage check
- switch (keys){
- case 0:
- delay(100);
- if((analogRead(A6)*10) < VBATMIN){
- lcd.clear();
- lcd.print("Bateria");
- lcd.setCursor(0, 1);
- lcd.print("Roz\x02adowana!");
- delay(2000);
- wylacz();
- }
- break;
- case (1<<0)://D -- zakonczenie paragonu
- if(suma_cen == 0){
- lcd.clear();
- sprintf(buff, "Vb=%d mV; v" VERSION,analogRead(A6)*10 );
- lcd.print(buff);
- lcd.setCursor(0, 1);
- sprintf(buff, "PWc=%d PrC=%d",powerCounter, printCounter);
- lcd.print(buff);
- delay(2000);
- lcd_powitanie();
- }
- else{
- printFooter();
- }
- break;
- case (1<<1)://#
- wybranyProdukt = 12;
- break;
- case (1<<2)://0
- wybranyProdukt = 10;
- break;
- case (1<<3)://*
- wybranyProdukt = 11;
- break;
- case (1<<4)://C
- //change cashier
- if(suma_cen == 0){
- cashier = (++cashier) % 3;
- lcd_powitanie();
- }
- break;
- case (1<<5)://9
- wybranyProdukt = 9;
- break;
- case (1<<6)://8
- wybranyProdukt = 8;
- break;
- case (1<<7)://7
- wybranyProdukt = 7;
- break;
- case (1<<8)://B
- if(suma_cen == 0){
- //wydrukuj cos innego
- drukarka.print("\x1B\x61\x48"); //alignment left
- drukarka.print(" ,~~.\r\
- ( 6 )-_,\r\
- ('\___ )=='-' KACZKA\r\
- \\ . ) )\r\
- \\ `-' / \r\
- ~'`~'`~'`~'`~\r\r\r");
- drukarka.print("\x1B\x61\x49"); //alignment middle
- }
- break;
- case (1<<9)://6
- wybranyProdukt = 6;
- break;
- case (1<<10)://5
- wybranyProdukt = 5;
- break;
- case (1<<11)://4
- wybranyProdukt = 4;
- break;
- case (1<<12)://A
- if(suma_cen > 0)
- printFooter(); //zakoncz paragon przed wylaczeniem
- wylacz();
- break;
- case (1<<13)://3
- wybranyProdukt = 3;
- break;
- case (1<<14)://2
- wybranyProdukt = 2;
- break;
- case (1<<15)://1
- wybranyProdukt = 1;
- break;
- }
- if(wybranyProdukt){
- int isFirst=0;
- if(suma_cen == 0) isFirst=1;//pierwszy produkt na tym paragonie,
- strcpy_P(buff, (PGM_P)pgm_read_word(&(produkty[wybranyProdukt-1])));
- uint8_t a = strlen(buff);
- uint16_t cena = pgm_read_word(&(ceny[wybranyProdukt-1]));
- suma_cen += cena;
- lcd.clear();
- lcd.print(buff);
- itoa(cena, buff, 10);
- lcd.setCursor(15-2-strlen(buff), 0);
- lcd.print(buff);
- lcd.print(" Z\x02");
- lcd.setCursor(0, 1);
- sprintf(buff, "SUMA: %7d Z\x02",suma_cen);
- lcd.print(buff);
- ;
- if(isFirst) {
- printHeader();
- isFirst=0;
- }
- //drukowanie pozycji na paragonie
- strcpy_P(buff, (PGM_P)pgm_read_word(&(produkty[wybranyProdukt-1])));
- //zamiana \x02 na \x9D
- for (char* p = buff; p = strchr(p, 0x02); ++p) {
- *p = 0x9D;
- }
- drukarka.print(buff);
- int spacje = 32-7-a;
- for(uint8_t k=0;k<spacje;++k){drukarka.print(" ");}
- sprintf(buff, "%4d Z\x9D\r", cena);
- drukarka.print(buff);
- delay(500);
- wybranyProdukt = 0;
- }
- //test odczytu klawiatury
- /*
- lcd.clear();
- lcd16Bit(keys);
- lcd.setCursor(0, 1);
- lcd16Bit(keyState);
- */
- //test odczytu z pamieci FLASH i wyswietlania
- /*
- for (unsigned char i = 0; i < baza; i++)
- {
- delay(1000);
- }
- */
- powerFunction();
- delay(10);
- }
- uint16_t getKeyState(){
- //3 .. 10 - 4x4 keyboard matrix
- uint16_t reads=0;
- pinMode(3, INPUT_PULLUP);
- pinMode(4, INPUT_PULLUP);
- pinMode(5, INPUT_PULLUP);
- pinMode(6, INPUT_PULLUP);
- pinMode(7, INPUT);
- pinMode(8, INPUT);
- pinMode(9, INPUT);
- pinMode(10, INPUT);
- digitalWrite(7, LOW);
- digitalWrite(8, LOW);
- digitalWrite(9, LOW);
- digitalWrite(10, LOW);
- //col A
- pinMode(7, OUTPUT);
- delay(1);
- reads += (((PIND & 0x78)>>3) << 0);
- pinMode(7, INPUT);
- //col B
- pinMode(8, OUTPUT);
- delay(1);
- reads += (((PIND & 0x78)>>3) << 4);
- pinMode(8, INPUT);
- //col C
- pinMode(9, OUTPUT);
- delay(1);
- reads += (((PIND & 0x78)>>3) << 8);
- pinMode(9, INPUT);
- //col D
- pinMode(10, OUTPUT);
- delay(1);
- reads += (((PIND & 0x78)>>3) << 12);
- pinMode(10, INPUT);
- return ~reads;
- }
- void lcd_powitanie()
- {
- lcd.clear();
- strcpy_P(buff, (PGM_P)pgm_read_word(&(powitania[cashier])));
- lcd.print(buff);
- lcd.setCursor(0, 1);
- strcpy_P(buff, (PGM_P)pgm_read_word(&(powitania[3])));
- lcd.print(buff);
- }
- void lcd16Bit(uint16_t number)
- {
- for (uint8_t i=0;i<16;i++)
- {
- if (((number >> (15-i)) & 0x01))
- {
- lcd.print("1");
- }
- else
- {
- lcd.print("0");
- }
- }
- }
- ///drukuje nagłówek paragonu
- void printHeader(){
- EEPROM.write(2, ++printCounter);
- strcpy_P(buff, (PGM_P)pgm_read_word(&(powitania[cashier])));
- drukarka.print("\x1B\x61\x49"); //alignment middle
- drukarka.print("\x1B\x45\x01"); //bold print
- drukarka.print("\x1B\x0E\x02"); //times 2 wider pattern
- drukarka.print(buff);
- drukarka.print("\x1B\x45\x00"); //bold print off
- drukarka.print("\x1B\x14\x02"); //cancel times wider pattern
- delay(30);
- sprintf(buff, "DZIEN DOBRY! \r\nPARAGON NR %d\r\n\x1D\x6B\x03",printCounter);
- drukarka.print(buff);
- sprintf(buff,"%08d", printCounter);
- drukarka.write((uint8_t)0);
- 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);
- drukarka.print(buff);
- //delay(2000);
- }
- void printFooter(){
- lcd.clear();
- lcd.print("Drukowanie ...");
- lcd.setCursor(0, 1);
- sprintf(buff, "SUMA: %7d Z\x02",suma_cen);
- lcd.print(buff);
- sprintf(buff, "\x1B\x61\x50+ \r\x1B\x61\x49================================\r\n");
- drukarka.print(buff);
- delay(100);
- sprintf(buff, "RAZEM:%23d Z\x9D\r\rDO WIDZENIA!\r\r\r\r",suma_cen);
- drukarka.print(buff);
- delay(100);
- suma_cen = 0;
- lcd_powitanie();
- }
- uint16_t keyDown(){
- uint16_t ret;
- lastKeyState = keyState;
- keyState = getKeyState();
- ret = ((keyState^lastKeyState)&keyState);
- return ret;
- }
- void powerFunction(){
- //Power function:
- unsigned long czas = millis();
- if((lastAction+idle) < czas )
- wylacz();
- //actions:
- //lastAction = millis();
- }
- void wylacz(){
- lcd.clear();
- strcpy_P(buff, (PGM_P)pgm_read_word(&(powitania[(powerCounter % 3)])));
- lcd.print(buff);
- lcd.setCursor(0, 1);
- strcpy_P(buff, (PGM_P)pgm_read_word(&(powitania[4])));
- lcd.print(buff);
- delay(2000);
- lcd.clear();
- digitalWrite(POWER_CTL, LOW);
- for(;;){};
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement