/*-------------------------------------------------------------------------+ | | | Tokio Drift | | Copyright (C) 2011 DICo Arduino Team | | | | | | This program is free software: you can redistribute it and/or modify | | it under the terms of the GNU General Public License as published by | | the Free Software Foundation, either version 3 of the License, or | | (at your option) any later version. | | | | This program is distributed in the hope that it will be useful, | | but WITHOUT ANY WARRANTY; without even the implied warranty of | | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | | GNU General Public License for more details. | | | | You should have received a copy of the GNU General Public License | | along with this program. If not, see <http://www.gnu.org/licenses/>. | | | +-------------------------------------------------------------------------*/ //////////////////////////////////////////////////////////////////////////// // Siti da cui abbiamo preso idee e codice /** * ID-12 * http://bildr.org/2011/02/rfid-arduino/ */ /** * IR * http://www.arcfn.com/2009/08/multi-protocol-infrared-remote-library.html */ /** * SparkFun LCD * http://www.arduino.cc/playground/Learning/SparkFunSerLCD /* //////////////////////////////////////////////////////////////////////////// // Struttura dati in output dal RFID Reader ID-12 /** * |STX| [DATA] | [CHECKSUM] |CR|NL|ETX| * * [DATA] = | [B1_HEX1] | [B1_HEX2] | [B2_HEX3] | ... | [B5_HEX10] | * [CHECKSUM] = | [B_HEX1] | [B_HEX2] | * * STX = 0000 0010 | CR = 0000 1101 | NL = 0000 1010 | ETX = 0000 0011 * B1..B5 = IC CARD DATA (5bytes) * B1 = HEX1 + HEX2 .. B5 = HEX9 + HEX10 * CHECKSUM = B1 XOR B2 XOR B3 XOR B4 XOR B5 (1byte) /* /** * nomenclatura funzioni: <keyword>_<fun> */ //////////////////////////////////////////////////////////////////////////// #include <IRremote.h> //////////////////////////////////////////////////////////////////////////// // Globals (configurazione) const char* VERSION = "v0.4 TokioDrift"; // VERSION /** * TAGS */ char* tagA = "21003BDAE6"; // admin char* tagH = "21003BC77C"; // homebase // andra' riletto a step 10 //////////////11111111112222222222333333333344444444445555555555666666666677777777778888888888bbbbbbbbbb // bbbb e' la "bottiglietta" char* tags = "21003BA83921003BE7CF21003BA8CF21003BDA9D21003BF50121003BC43E21003BD57621003B91EA00365F8FD0"; const int NRTAGS=8; /** * IR */ const int IR_PIN = 11; // infrarosso decode_results results; // struttura dati per IR IRrecv irrecv(IR_PIN); // setup libreria IR /** * Mapped IR key codes */ const long IRcodes_number[] = { 16724685, 16740495, 16757325, 16773645, 16741005, 16764975, 16732845, 16716525 }; const int IRcodes_len = 8; const long IRcodes_ok = 16755285; const long IRcodes_exit = 16718055; const long IRcodes_sx = 16769565; const long IRcodes_dx = 16754775; const long IRcodes_up = 16736925; const long IRcodes_down = 16738455; boolean t1 = false; boolean t2 = false; /* const int STOP_PIN = 2; // paraurti PIN2 per interrupt 0 const int STOP_INTERRUPT = 0; // paraurti PIN2 per interrupt 0 */ // const int EMPTY_PIN = TBD; // sensore vuoto/pieno const int LCD_PIN = 1; // uscita seriale lcd (TX) const int TAGREADER_PIN = 0; // ingresso seriale ID-12 (RX) const int TAGREADER_RESET_PIN = 13; // reset lettore ID-12 const int ENGINE_SX_PIN = 8; // motore sx const int ENGINE_DX_PIN = 9;//motore sx // motore const int LED_PIN = 12;//gin LED char tagString[11]; char tagCustomer[11]; /** * Costanti ognuna delle quali definisce uno stato */ const int STOP = 0; const int MOTORETTILINEO = 1; const int MOTODX = 2; const int MOTOSX = 3; const int DEBUG = 99; /** * Valore del delay motore */ int delayMotore =100; /** * Stato dell'automa */ int currentState = STOP; // stato delle attivazioni boolean engine_sx_state = false; boolean engine_dx_state = false; //boolean led1 = false; //boolean led2 = false; // etc... //////////////////////////////////////////////// // Setup (Once) void setup() { // resetta tutti i pin (per sicurezza) for (int i=0; i<=13; i++) { pinMode(i, OUTPUT); } /*for(int i=0;i<=13;i++) {digitalWrite(i, LOW); // set the LED off delay(100); // wait }*/ // ciclo di attivazione (motori, luci, etc.) pinMode(ENGINE_DX_PIN, OUTPUT); pinMode(ENGINE_SX_PIN, OUTPUT); digitalWrite(ENGINE_DX_PIN, engine_dx_state); digitalWrite(ENGINE_SX_PIN, engine_sx_state); // IR sensor Serial.begin(9600); irrecv.enableIRIn(); // Start the receiver // TAG reader pinMode(TAGREADER_RESET_PIN, OUTPUT); digitalWrite(TAGREADER_RESET_PIN, HIGH); tagReader_reset(); tagReader_clearTag(tagCustomer); tagReader_clearTag(tagString); delay(3000); // per vedere lo splash screen del LCD } //////////////////////////////////////////////// // LOOP (Main) void loop() { //selectLineOne(); // non va lcd_clear(); Serial.print(VERSION); delay(100); lcd_clear(); /** * ciclo di lettura di tutti gli ingressi (IR e RFID) * legge e memorizza in un buffer (globale) */ /* LED ACCESO */ digitalWrite(LED_PIN, HIGH); /* IR */ results.value = 0; ir_read(); if (results.value>0) { Serial.print("i:"); Serial.print(results.value); Serial.print(" "); } /*if (results.value == IRcodes_exit) { delay(5000); }*/ /*if (results.value == IRcodes_sx) { currentState = DEBUG; } if (results.value == IRcodes_dx) { currentState = STOP; // resetta i valori tagReader_clearTag(tagCustomer); tagReader_clearTag(tagString); }*/ /* TAG */ /*tagReader_read(); if (strlen(tagString) > 0) { Serial.print("t:"); Serial.print(tagString); Serial.print(" "); }*/ /** * tagReader_compareTag funziona correttamente * if(tagReader_compareTag(tagString, tagA)) Serial.print(" K_a"); * if(tagReader_compareTag(tagString, tagH)) Serial.print(" K_h"); * Serial.print(" TA_L:"); * Serial.print(strlen(tagA)); * Serial.print(" TH_L:"); * Serial.print(strlen(tagH)); * Serial.print(" TS_L:"); * Serial.print(strlen(tagString)); * Serial.print(" TAGS:"); * Serial.print(strlen(tags)); */ //delay(5000); //compare(tagA, tags, ir_tagIndex(results.value)) Serial.print(" OK "); //delay(2000); /** * AUTOMA * eventuale cambio stato (sia stato dell'automa sia stato di attivazione motori e luci etc.) */ Serial.print("s:"); Serial.print(currentState); Serial.print(" "); /* Ciclo di attivazione (motori, luci, etc.) */ digitalWrite(ENGINE_DX_PIN, engine_dx_state); digitalWrite(ENGINE_SX_PIN, engine_sx_state); switch (currentState) { case STOP: state_stop(); break; case MOTORETTILINEO: state_motoRettilineo(); break; case MOTODX: state_motoDx(); break; case MOTOSX: state_motoSx(); break; /*case DEBUG: for(int j=10;j<=20;j=j+5) { for(int i=0;i<=13;i++) ledblink(i,j); for(int i=13;i>=0;i--) ledblink(i,j); } break;*/ } /* digitalWrite(ENGINE_DX_PIN, LOW); digitalWrite(ENGINE_SX_PIN, LOW) */ digitalWrite(LED_PIN, LOW); /* Debugging... */ /* Serial.print("t1="); Serial.print(t1, DEC); Serial.print("t2="); Serial.print(t2, DEC); */ /* if (strlen(tagCustomer) > 0) { Serial.print("tc="); Serial.print(tagCustomer); Serial.print(" "); } if (results.value > 0) { Serial.print("rv="); Serial.print(results.value); Serial.print(" "); } // per "debugging", cosi' si vede se fa qualcosa Serial.print("ms:"); Serial.print(millis()); //Serial.println(); tagReader_reset(); delay(100); */ } //////////////////////////////////////////////// //LIBRERIE & FUNZIONI /** * Checks two char strings to see if they are equal. Index * simulates a matrix of dimension (nr_keys x key_length) * * Example: on a 100 char array (key length 10) we insert 6 to * verify the 6th position (index * key_length = base_index) */ boolean string_compare(char* key, char* table, int index) { int key_len = strlen(key); /* If empty then exit */ if (key_len == 0) return false; /* Compare each char of the strings */ for (int i = 0; i < key_len; i++) { /* If key charAt(i) is not equal to table char, false */ if (key[i] != table[(key_len * index) + i]) return false; } /* No mismatches, equal strings */ return true; } /////////////////////////////////////////////////////////////////////////// // AUTOMA /* 0) STOP: entrambi motori fermi 1) MOTORETTILINEO: entrambi motori accesi 2) MOTODX: motore sx acceso, motore dx spento 3) MOTOSX: motore dx acceso, motore sx spento */ /* STATI OLD void state_STOP() { engine_state = false; // ammesso che string_compare vada bene if (tagReader_compareTag(tagA, tagString)) currentState = ADMINCARICO; } void state_ADMINCARICO() { engine_state = false; // fare lettura complessa da IR (serve nr customer e OK) if (results.value != 0 && tagReader_mappedCustomer()) { // accende il motore, cambia stato e va in consegna engine_state = true; currentState = INMOTOCONSEGNA; } } void state_INMOTOCONSEGNA() { engine_state = true; lcd_clear(); Serial.print("CLIENTE: "); Serial.print(tagReader_tagIndex(tagCustomer)); //Serial.print("================"); delay(500); lcd_clear(); if (tagReader_compareTag(tagCustomer, tagString)) { engine_state = false; currentState = STOPFORCONSEGNA; } else if (strlen(tagString) >0) { lcd_clear(); Serial.print("NO FREE BEER!!!!"); Serial.print("================"); delay(1000); lcd_clear(); } } void state_STOPFORCONSEGNA() { engine_state = false; // clear lcd, stampa PRENDI!!!LA, delay lcd_clear(); Serial.print("PRENDI BEVANDA.."); Serial.print("Share and enjoy!"); delay(5000); lcd_clear(); tagReader_clearTag(tagCustomer); engine_state = true; currentState = INMOTORIENTRO; } void state_INMOTORIENTRO() { engine_state = true; if (tagReader_compareTag(tagA, tagString)) currentState = ADMINCARICO; else if (tagReader_compareTag(tagH, tagString)) currentState = STOP; } ////////////////////////////////////////////////////////// // TAG /** * Reset the RFID reader to read again */ void state_stop() { engine_sx_state = false; engine_dx_state = false; // ammesso che string_compare vada bene if (results.value == IRcodes_up) currentState = MOTORETTILINEO; } void state_motoRettilineo() { engine_sx_state = true; engine_dx_state = true; if(results.value == IRcodes_dx) currentState = MOTODX; else if (results.value == IRcodes_sx) currentState = MOTOSX; else if (results.value == IRcodes_up) currentState = MOTORETTILINEO; else if (results.value == IRcodes_down) currentState = STOP; } void state_motoDx() { engine_dx_state = false; engine_sx_state = true; delay(delayMotore); currentState = MOTORETTILINEO; } void state_motoSx() { engine_dx_state = true; engine_sx_state = false; delay(delayMotore); currentState = MOTORETTILINEO; } void tagReader_reset() { digitalWrite(TAGREADER_RESET_PIN, LOW); digitalWrite(TAGREADER_RESET_PIN, HIGH); // Output ID strig set to NULL // tagReader_clearTag(tagString); delay(150); } int tagReader_tagIndex(char* tag) { if(strlen(tag) == 0) return 9998; /* "i" is the base of each mapped key code on the array */ for (int i = 0; i < NRTAGS; i++) { /* if key code is mapped return tag index */ if(string_compare(tag, tags, i)) { return i+1; break; } } /* return 9999 if key code not found */ return 9999; } /** * Reads ID-12 output and saves the data in the * tagString array Remember that one frame is not * enough to read 64bit of ID */ void tagReader_read() { // Index byte read int index = 0; // Data structure state flag boolean reading = false; // (index < 10) = 5bytes data + 1byte checksum // = 1 Frames (check data block from second frame) while (Serial.available() && index < 10) { int readByte = Serial.read(); // Read next available byte if (readByte == 2) reading = true; // STX flag, begining of data if (readByte == 3) reading = false; // ETX flag, end of data // If byte read is not ETX/STX/CR/NL then store the // 5bytes of Tag ID and ignore 1byte of CHECKSUM if (reading && readByte != 2 && readByte != 13 && readByte != 10) { tagString[index] = readByte; index++; } } tagString[index] = 0; } /** * Clear the char array by filling with null - ASCII 0 */ void tagReader_clearTag(char* tag) { for (int i = 0; i < strlen(tag); i++) tag[i] = 0; } /** * Compare two values to see if same, * if strcmp not working 100% we do this... */ boolean tagReader_compareTag(char* tagOne, char* tagTwo) { return string_compare(tagOne, tagTwo, 0); } /** * Checks IR remote key value in the mapped keys array and * if it is present, sets the tagCustomer value coresponding * to the key */ boolean tagReader_mappedCustomer() { /* scorre la lista degli input mappati dall'IR */ int i = ir_tagIndex(results.value); /* * se l'input è stato mappato, copia l'ID del tag * nel buffer tagCustomer */ if (i != 9999) { for (int j = 0; j < 10; j++) { tagCustomer[j] = tags[(i * 10) + j]; } return true; } return false; } /////////////////////////////////////////////////////////////////////////// /// IR /** * Reads the 6 hex key code pressed on the remote * and compares it to the array of mapped keys * giving in output the index of the assigned tag, * or 9999 if the key code is not mapped */ int ir_tagIndex(long ir_code) { if(ir_code == 0) return 9998; /* "i" is the base of each mapped key code on the array */ for (int i = 0; i < IRcodes_len; i++) { /* if key code is mapped return tag index */ if (IRcodes_number[i] == ir_code){ return i; break; } } /* return 9999 if key code not found */ return 9999; } /** * Reads the key code pressend on the remote and * saves the value in the structure results */ boolean ir_read() { boolean out = false; if (irrecv.decode(&results)) { out = true; irrecv.resume(); // Receive the next value } return out; } /////////////////////////////////////////////////////////////////////////// // LCD (verificare se questi codici funzionano con lo sparkfun) void lcd_clear() { Serial.print(0xFE, BYTE); //command flag Serial.print(0x01, BYTE); //clear command. delay(100); } /* void lcd_selectLineOne() { //puts the cursor at line 0 char 0. Serial.print(0xFE, BYTE); //command flag Serial.print(128, BYTE); //position delay(10); } */ /* void lcd_selectLineTwo() { //puts the cursor at line 0 char 0. Serial.print(0xFE, BYTE); //command flag Serial.print(192, BYTE); //position delay(10); } */ /* void lcd_goTo(int position) { //position = line 1: 0-15, line 2: 16-31, 31+ defaults back to 0 if (position<16) { Serial.print(0xFE, BYTE); //command flag Serial.print((position+128), BYTE); //position } else if (position<32) { Serial.print(0xFE, BYTE); //command flag Serial.print((position+48+128), BYTE); //position } else { goTo(0); } delay(10); } */ /* void lcd_backlightOn() { //turns on the backlight Serial.print(0x7C, BYTE); //command flag for backlight stuff Serial.print(157, BYTE); //light level. delay(10); } */ /* void lcd_backlightOff() { //turns off the backlight Serial.print(0x7C, BYTE); //command flag for backlight stuff Serial.print(128, BYTE); //light level for off. delay(10); } */ void ledblink(int i, int ms) { digitalWrite(i, HIGH); // set the LED on delay(ms); // wait digitalWrite(i, LOW); // set the LED off delay(ms); // wait }