User Tools

Site Tools


pub:arduino:codice_sorgente_arducameriere

18 giugno 2011 nuovo reader, sistemati alcuni minor

/*-------------------------------------------------------------------------+
|									   |
| Arduino Cameriere							   |
| 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 = "v105 sl-lab.it"; // 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;
 
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_PIN = 8; // motore
 
char tagString[11];
char tagCustomer[11];
 
/**
* Costanti ognuna delle quali definisce uno stato
*/
const int STOP = 0;
const int ADMINCARICO = 1;
const int INMOTOCONSEGNA = 2;
const int STOPFORCONSEGNA = 3;
const int INMOTORIENTRO = 4;
 
const int DEBUG = 99;
 
/**
* Stato dell'automa
*/
int currentState = STOP;
 
// stato delle attivazioni
boolean engine_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_PIN, OUTPUT);
    digitalWrite(ENGINE_PIN, engine_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(500);
    lcd_clear();
 
    /**
    * ciclo di lettura di tutti gli ingressi (IR e RFID)
    * legge e memorizza in un buffer (globale)
 
 
    */
 
    /* 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(" ");
    switch (currentState) {
    case STOP:
        state_STOP();
        break;
    case ADMINCARICO:
        state_ADMINCARICO();
        break;
    case INMOTOCONSEGNA:
        state_INMOTOCONSEGNA();
        break;
    case STOPFORCONSEGNA:
        state_STOPFORCONSEGNA();
        break;
    case INMOTORIENTRO:
        state_INMOTORIENTRO();
        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;
    }
 
    /* Ciclo di attivazione (motori, luci, etc.) */
    digitalWrite(ENGINE_PIN, engine_state);
 
 
 
    /* 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(500);
}
 
 
////////////////////////////////////////////////
//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: motore fermo, modalita' controlla RFIDTAG (se admin goto 1)
1) ADMINCARICO: motore fermo, ****attesa IR (se OK su IR goto 2)
2) INMOTOCONSEGNA: motore acceso, controlla RFIDTAG (se customer corretto goto 3)
3) STOPFORSECONSEGNA: motore fermo, delay e goto 4
4) INMOTORIENTRO: motore acceso, controllo RFIDTAG (se admin goto 1, se HOMEBASE goto 0)
*/
 
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 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
}

17 giugno 2011 con giochino led su debug

/*-------------------------------------------------------------------------+
|									   |
| Arduino Cameriere							   |
| 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)
 
/**
* TAGS
*/
char* tagA = "21003BDAE6"; // admin
char* tagH = "21003BC77C"; // homebase
 
// andra' riletto a step 10
//////////////11111111112222222222333333333344444444445555555555666666666677777777778888888888bbbbbbbbbb // bbbb e' la "bottiglietta"
char* tags = "21003BA83921003BE7CF21003BA8CF21003BDA9D21003BF50121003BC43E21003BD57621003B91EA00365F8FD0";
 
/**
* 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;
 
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_PIN = 8; // motore
 
char tagString[11];
char tagCustomer[11];
 
/**
* Costanti ognuna delle quali definisce uno stato
*/
const int STOP = 0;
const int ADMINCARICO = 1;
const int INMOTOCONSEGNA = 2;
const int STOPFORCONSEGNA = 3;
const int INMOTORIENTRO = 4;
 
const int DEBUG = 99;
 
/**
* Stato dell'automa
*/
int currentState = STOP;
 
// stato delle attivazioni
boolean engine_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_PIN, OUTPUT);
    digitalWrite(ENGINE_PIN, engine_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);
}
 
////////////////////////////////////////////////
// LOOP (Main)
 
void loop() {
    //selectLineOne(); // non va
    lcd_clear();
 
    /**
    * ciclo di lettura di tutti gli ingressi (IR e RFID)
    * legge e memorizza in un buffer (globale)
    */
 
    /* 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(10000);
    }
 
    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);
    switch (currentState) {
    case STOP:
        state_STOP();
        break;
    case ADMINCARICO:
        state_ADMINCARICO();
        break;
    case INMOTOCONSEGNA:
        state_INMOTOCONSEGNA();
        break;
    case STOPFORCONSEGNA:
        state_STOPFORCONSEGNA();
        break;
    case INMOTORIENTRO:
        state_INMOTORIENTRO();
        break;
    case DEBUG:
      for(int j=5;j<=20;j++)
      {
        for(int i=0;i<=13;i++)
           ledblink(i,j);
        for(int i=13;i>=0;i--)
           ledblink(i,j);
      }
      break;
    }
 
    /* Ciclo di attivazione (motori, luci, etc.) */
    digitalWrite(ENGINE_PIN, engine_state);
 
 
 
    /* 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);
    }
    if (results.value > 0) {
        Serial.print(",rv=");
        Serial.print(results.value);
    }
    // per "debugging", cosi' si vede se fa qualcosa
    Serial.print(",ms:");
    Serial.print(millis());
    Serial.println();
    tagReader_reset();
    delay(1000);
}
 
 
////////////////////////////////////////////////
//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: motore fermo, modalita' controlla RFIDTAG (se admin goto 1)
1) ADMINCARICO: motore fermo, ****attesa IR (se OK su IR goto 2)
2) INMOTOCONSEGNA: motore acceso, controlla RFIDTAG (se customer corretto goto 3)
3) STOPFORSECONSEGNA: motore fermo, delay e goto 4
4) INMOTORIENTRO: motore acceso, controllo RFIDTAG (se admin goto 1, se HOMEBASE goto 0)
*/
 
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;
    Serial.print("CLIENTE NR: ");    
    Serial.print(tagReader_tagIndex(tagCustomer));
    Serial.print("================");
 
    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(2000);
    }
 
}
 
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);
    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 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 < 8; i++) {
        /* if key code is mapped return tag index */
        if(string_compare(tag, tags, i))
        {
            return i;
            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(10);
}
 
/*
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
}

17 giugno 2011

/*-------------------------------------------------------------------------+
|									   |
| Arduino Cameriere							   |
| 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)
 
/**
* TAGS
*/
char* tagA = "21003BDAE6"; // admin
char* tagH = "21003BC77C"; // homebase
 
// andra' riletto a step 10
//////////////11111111112222222222333333333344444444445555555555666666666677777777778888888888bbbbbbbbbb // bbbb e' la "bottiglietta"
char* tags = "21003BA83921003BE7CF21003BA8CF21003BDA9D21003BF50121003BC43E21003BD57621003B91EA00365F8FD0";
 
/**
* 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;
 
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_PIN = 8; // motore
 
char tagString[11];
char tagCustomer[11];
 
/**
* Costanti ognuna delle quali definisce uno stato
*/
const int STOP = 0;
const int ADMINCARICO = 1;
const int INMOTOCONSEGNA = 2;
const int STOPFORCONSEGNA = 3;
const int INMOTORIENTRO = 4;
 
const int DEBUG = 99;
 
/**
* Stato dell'automa
*/
int currentState = STOP;
 
// stato delle attivazioni
boolean engine_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, INPUT);
    }
    /*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_PIN, OUTPUT);
    digitalWrite(ENGINE_PIN, engine_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);
}
 
////////////////////////////////////////////////
// LOOP (Main)
 
void loop() {
    //selectLineOne(); // non va
    lcd_clear();
 
    /**
    * ciclo di lettura di tutti gli ingressi (IR e RFID)
    * legge e memorizza in un buffer (globale)
    */
 
    /* 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(10000);
    }
 
    if (results.value == IRcodes_sx) {
        currentState = DEBUG;
    }
 
    if (results.value == IRcodes_dx) {
        currentState = STOP; // non 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);
    switch (currentState) {
    case STOP:
        state_STOP();
        break;
    case ADMINCARICO:
        state_ADMINCARICO();
        break;
    case INMOTOCONSEGNA:
        state_INMOTOCONSEGNA();
        break;
    case STOPFORCONSEGNA:
        state_STOPFORCONSEGNA();
        break;
    case INMOTORIENTRO:
        state_INMOTORIENTRO();
        break;
    }
 
    /* Ciclo di attivazione (motori, luci, etc.) */
    digitalWrite(ENGINE_PIN, engine_state);
 
 
 
    /* 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);
    }
    if (results.value > 0) {
        Serial.print(",rv=");
        Serial.print(results.value);
    }
    // per "debugging", cosi' si vede se fa qualcosa
    Serial.print(",ms:");
    Serial.print(millis());
    Serial.println();
    tagReader_reset();
    delay(1000);
}
 
 
////////////////////////////////////////////////
//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: motore fermo, modalita' controlla RFIDTAG (se admin goto 1)
1) ADMINCARICO: motore fermo, ****attesa IR (se OK su IR goto 2)
2) INMOTOCONSEGNA: motore acceso, controlla RFIDTAG (se customer corretto goto 3)
3) STOPFORSECONSEGNA: motore fermo, delay e goto 4
4) INMOTORIENTRO: motore acceso, controllo RFIDTAG (se admin goto 1, se HOMEBASE goto 0)
*/
 
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;
    Serial.print("CLIENTE NR: ");    
    Serial.print(tagReader_tagIndex(tagCustomer));
    Serial.print("================");
 
    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(2000);
    }
 
}
 
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);
    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 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 < 8; i++) {
        /* if key code is mapped return tag index */
        if(string_compare(tag, tags, i))
        {
            return i;
            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(10);
}
 
/*
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);
}
*/

16 giugno 2011 (beta, ripristinate mancanze)

Questo e' testato e va (abbiamo cambiato PIN motore con rele' sicuramente ok), fatto test completo (sequenza con HOME+ADMIN finale e con ADMIN direttamente). Ho video dimostrativo ;)

C'e' da rimappare i TAG perche' sono sballati (tranne HOME e ADMIN).

C'e' da preparare presentazione http://arduinocamp.com/Events/PechaKucha e da scegliere un candidato che presenti (se non ve la sentite faccio io pero' ditemelo subito che preferisco prep io le mie slide ;) ).

Se volete partire da queste note

TBD se c'e' tempo, check dei codici di controllo LCD

/*-------------------------------------------------------------------------+
|									   |
| Arduino Cameriere							   |
| 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)
 
/**
* TAGS
*/
char* tagA = "21003BDAE6"; // admin
char* tagH = "21003BC77C"; // homebase
 
// andra' riletto a step 10
//////////////11111111112222222222333333333344444444445555555555666666666677777777778888888888bbbbbbbbbb // bbbb e' la "bottiglietta"
char* tags = "21003BA83921003BE7CF21003BA8CF21003BDA9D21003BF50121003BC43E21003BD57621003B91EA00365F8FD0";
//OLD //char* tags = "21003BE7CF21003BA8CF21003BDA9D21003BF50121003BC43E21003BD57621003B91EA21003BDAE6";
 
/**
* 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;
 
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_PIN = 8; // motore
 
char tagString[11];
char tagCustomer[11];
 
/**
* Costanti ognuna delle quali definisce uno stato
*/
const int STOP = 0;
const int ADMINCARICO = 1;
const int INMOTOCONSEGNA = 2;
const int STOPFORCONSEGNA = 3;
const int INMOTORIENTRO = 4;
 
const int DEBUG = 99;
 
/**
* Stato dell'automa
*/
int currentState = STOP;
 
// stato delle attivazioni
boolean engine_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, INPUT);
    }
    /*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_PIN, OUTPUT);
    digitalWrite(ENGINE_PIN, engine_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);
}
 
////////////////////////////////////////////////
// LOOP (Main)
 
void loop() {
    //selectLineOne(); // non va
    lcd_clear();
 
    /**
    * ciclo di lettura di tutti gli ingressi (IR e RFID)
    * legge e memorizza in un buffer (globale)
    */
 
    /* 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(10000);
    }
 
    if (results.value == IRcodes_sx) {
        currentState=DEBUG;
    }
 
    if (results.value == IRcodes_dx) {
        currentState=STOP; // non resetta i valori!!!
    }
 
    /* TAG */
    tagReader_read();
    if (strlen(tagString) > 1) {
        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);
    switch (currentState) {
    case STOP:
        state_STOP();
        break;
    case ADMINCARICO:
        state_ADMINCARICO();
        break;
    case INMOTOCONSEGNA:
        state_INMOTOCONSEGNA();
        break;
    case STOPFORCONSEGNA:
        state_STOPFORCONSEGNA();
        break;
    case INMOTORIENTRO:
        state_INMOTORIENTRO();
        break;
    }
 
    /* Ciclo di attivazione (motori, luci, etc.) */
    digitalWrite(ENGINE_PIN, engine_state);
 
 
 
    /* 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);
    }
    if (results.value>0) {
        Serial.print(",rv=");
        Serial.print(results.value);
    }
    // per "debugging", cosi' si vede se fa qualcosa
    Serial.print(",ms:");
    Serial.print(millis());
    Serial.println();
    tagReader_reset();
    delay(1000);
}
 
 
////////////////////////////////////////////////
//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: motore fermo, modalita' controlla RFIDTAG (se admin goto 1)
1) ADMINCARICO: motore fermo, ****attesa IR (se OK su IR goto 2)
2) INMOTOCONSEGNA: motore acceso, controlla RFIDTAG (se customer corretto goto 3)
3) STOPFORSECONSEGNA: motore fermo, delay e goto 4
4) INMOTORIENTRO: motore acceso, controllo RFIDTAG (se admin goto 1, se HOMEBASE goto 0)
*/
 
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;
    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(2000);
    }
 
}
 
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);
    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 tagReader_reset()
{
    digitalWrite(TAGREADER_RESET_PIN, LOW);
    digitalWrite(TAGREADER_RESET_PIN, HIGH);
    // Output ID strig set to NULL
    // tagReader_clearTag(tagString);
    delay(150);
}
 
/**
* 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)
{
    /* "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;
    }
    /* 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(10);
}
 
/*
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);
}
*/

16 giugno 2011 (alpha)

///////////////////////////////////////////////////////////////////////////
// Arduino Cameriere
// 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)
 
// TAGS
char* tagA = "21003BDAE6"; // admin
char* tagH = "21003BC77C"; // homebase
 
// andra' riletto a step 10 
////////////////11111111112222222222333333333344444444445555555555666666666677777777778888888888bbbbbbbbbb // bbbb e' la "bottiglietta"
  char* tags = "21003BA83921003BE7CF21003BA8CF21003BDA9D21003BF50121003BC43E21003BD57621003B91EA00365F8FD0";
//char* tags = "21003BE7CF21003BA8CF21003BDA9D21003BF50121003BC43E21003BD57621003B91EA21003BDAE6";
 
// 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;
 
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_PIN = 8; // motore
 
char tagString[11];
char tagCustomer[11];
 
// costanti ognuna delle quali definisce uno stato
const int STOP = 0;
const int ADMINCARICO = 1;
const int INMOTOCONSEGNA = 2;
const int STOPFORCONSEGNA = 3;
const int INMOTORIENTRO = 4;
 
const int DEBUG = 99;
 
// stato dell'automa
int currentState = STOP;
 
// stato delle attivazioni
boolean engine_state = false;
//boolean led1 = false;
//boolean led2 = false;
// etc...
 
////////////////////////////////////////////////
////////////////////////////////////////////////
void setup()
{  
  // resetta tutti i pin (per sicurezza)
  for(int i=0;i<=13;i++)
  {pinMode(i, INPUT);}
  /*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_PIN, OUTPUT);
    digitalWrite(ENGINE_PIN, engine_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);
}
 
////////////////////////////////////////////////
void loop() {
    //selectLineOne(); // non va
    lcd_clear();
 
    // ciclo di lettura di tutti gli ingressi (IR e RFID)
    // legge e memorizza in un buffer (globale)
 
    // 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(10000);
    }
 
    if (results.value == IRcodes_sx){
      currentState=DEBUG;
    }
 
    if (results.value == IRcodes_dx){
      currentState=STOP; // non resetta i valori!!!
    }
 
    // TAG
    tagReader_read();
    if(strlen(tagString) > 1){
      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);
    switch (currentState) {
      case STOP:
        state_STOP();
        break;
      case ADMINCARICO:
        state_ADMINCARICO();
        break;
      case INMOTOCONSEGNA:
        state_INMOTOCONSEGNA();
        break;
      case STOPFORCONSEGNA:
        state_STOPFORCONSEGNA();
        break;
      case INMOTORIENTRO:
        state_INMOTORIENTRO();
        break;
    }
 
    // ciclo di attivazione (motori, luci, etc.)
    digitalWrite(ENGINE_PIN, engine_state);
 
 
 
    // 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);
    }
    if(results.value>0){
     Serial.print(",rv=");
     Serial.print(results.value);
    }
    // per "debugging", cosi' si vede se fa qualcosa
    Serial.print(",ms:");
    Serial.print(millis());
    Serial.println();
    tagReader_reset();
    delay(1000);
}
 
 
////////////////////////////////////////////////
////////////////////////////////////////////////
//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: motore fermo, modalita' controlla RFIDTAG (se admin goto 1)
1) ADMINCARICO: motore fermo, ****attesa IR (se OK su IR goto 2)
2) INMOTOCONSEGNA: motore acceso, controlla RFIDTAG (se customer corretto goto 3)
3) STOPFORSECONSEGNA: motore fermo, delay e goto 4
4) INMOTORIENTRO: motore acceso, controllo RFIDTAG (se admin goto 1, se HOMEBASE goto 0)
*/
 
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)    
    {
       // scorre la lista degli input mappati dall'IR
        for(int i = 0; i < IRcodes_len; i++){
          t1=true;          
          // trova l'indice del codice corrispondente al tag
          if(IRcodes_number[i] == results.value){
            t2=true;
            // copia il tag corrispondente all'indice nel tag customer
            for(int j = 0; j < 10; j++){
              tagCustomer[j] = tags[(i * 10) + j];
            }
          }
        }
        // accende il motore, cambia stato e va in consegna
     	engine_state = true;
        currentState = INMOTOCONSEGNA;
    }
 }
 
void state_INMOTOCONSEGNA() {
    engine_state = true;
    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(2000);
    }
 
}
 
void state_STOPFORCONSEGNA() {
    engine_state = false;
 
    // clear lcd, srampa PRENDI!!! LO, delay
    lcd_clear();
    Serial.print("PRENDI BEVANDA..");
    Serial.print("Share and enjoy!");
    delay(5000);
    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 and sets the 
// tagString to NULL.
void tagReader_reset() 
{
    digitalWrite(TAGREADER_RESET_PIN, LOW);
    digitalWrite(TAGREADER_RESET_PIN, HIGH);
    // Output ID strig set to NULL
    // tagReader_clearTag(tagString);
    delay(150);
}
 
// Reading ID-12 Output
// 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);
}
 
///////////////////////////////////////////////////////////////////////////
/// 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(int ir_code)
{
  /* "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;
  }
  /* return 9999 if key code not found */
  return 9999;
}
 
// Gestione lettura IR
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(10);
}
 
/*
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);
}
*/

16 giugno 2011 ter

///////////////////////////////////////////////////////////////////////////
// Arduino Cameriere
// 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)
 
// TAGS
char* tagA = "21003BDAE6"; // admin
char* tagH = "21003BC77C"; // homebase
 
// andra' riletto a step 10
char* tags = "21003BE7CF21003BA8CF21003BDA9D21003BF50121003BC43E21003BD57621003B91EA21003BDAE6";
 
// 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;
 
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_PIN = 3; // motore
 
char tagString[11];
char tagCustomer[11];
 
// costanti ognuna delle quali definisce uno stato
const int STOP = 0;
const int ADMINCARICO = 1;
const int INMOTOCONSEGNA = 2;
const int STOPFORCONSEGNA = 3;
const int INMOTORIENTRO = 4;
 
// stato dell'automa
int currentState = STOP;
 
// stato delle attivazioni
boolean engine_state = false;
//boolean led1 = false;
//boolean led2 = false;
// etc...
 
////////////////////////////////////////////////
////////////////////////////////////////////////
void setup()
{
    // 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);
}
 
////////////////////////////////////////////////
void loop() {
    //selectLineOne(); // non va
    lcd_clear();
 
    // ciclo di lettura di tutti gli ingressi (IR e RFID)
    // legge e memorizza in un buffer (globale)
 
    // IR
    if (ir_read()){
    	Serial.print("i:");
    	Serial.print(results.value);
        Serial.print(",");
    }
 
    if (results.value == IRcodes_exit){
      delay(10000);
    }
 
    // TAG
    tagReader_read();
    if(strlen(tagString) > 1){
      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);
    switch (currentState) {
      case STOP:
        state_STOP();
        break;
      case ADMINCARICO:
        state_ADMINCARICO();
        break;
      case INMOTOCONSEGNA:
        state_INMOTOCONSEGNA();
        break;
      case STOPFORCONSEGNA:
        state_STOPFORCONSEGNA();
        break;
      case INMOTORIENTRO:
        state_INMOTORIENTRO();
        break;
    }
 
    // ciclo di attivazione (motori, luci, etc.)
    digitalWrite(ENGINE_PIN, engine_state);
    Serial.print("t1=");
    Serial.print(t1, DEC);
    Serial.print("t2=");
    Serial.print(t2, DEC);
    Serial.print(" ");
    Serial.print(tagCustomer);
    Serial.print(" ");
    Serial.print(results.value);
    // per "debugging", cosi' si vede se fa qualcosa
    //    Serial.print(",ms:");
    //    Serial.print(millis());
    Serial.println();
    tagReader_reset();
    delay(1000);
}
 
 
////////////////////////////////////////////////
////////////////////////////////////////////////
//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: motore fermo, modalita' controlla RFIDTAG (se admin goto 1)
1) ADMINCARICO: motore fermo, ****attesa IR (se OK su IR goto 2)
2) INMOTOCONSEGNA: motore acceso, controlla RFIDTAG (se customer corretto goto 3)
3) STOPFORSECONSEGNA: motore fermo, delay e goto 4
4) INMOTORIENTRO: motore acceso, controllo RFIDTAG (se admin goto 1, se HOMEBASE goto 0)
*/
 
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)    
    {
       // scorre la lista degli input mappati dall'IR
        for(int i = 0; i < IRcodes_len; i++){
          t1=true;          
          // trova l'indice del codice corrispondente al tag
          if(IRcodes_number[i] == results.value){
            t2=true;
            // copia il tag corrispondente all'indice nel tag customer
            for(int j = 0; j < 10; j++){
              tagCustomer[j] = tags[(i * 10) + j];
            }
          }
        }
        // accende il motore, cambia stato e va in consegna
     	engine_state = true;
        currentState = INMOTOCONSEGNA;
    }
 }
 
void state_INMOTOCONSEGNA() {
    engine_state = true;
    if (tagReader_compareTag(tagCustomer, tagString))
    {
	engine_state = false;
        currentState = STOPFORCONSEGNA;
    }
}
 
void state_STOPFORCONSEGNA() {
    engine_state = false;
    // clear lcd, srampa PRENDI!!! LO, delay
    delay(5000);
    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 and sets the 
// tagString to NULL.
void tagReader_reset() 
{
    digitalWrite(TAGREADER_RESET_PIN, LOW);
    digitalWrite(TAGREADER_RESET_PIN, HIGH);
    // Output ID strig set to NULL
    // tagReader_clearTag(tagString);
    delay(150);
}
 
// Reading ID-12 Output
// 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);
}
 
///////////////////////////////////////////////////////////////////////////
/// 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(int ir_code)
{
  /* "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;
  }
  /* return 9999 if key code not found */
  return 9999;
}
 
// Gestione lettura IR
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(10);
}
 
/*
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);
}
*/

16 giugno 2011 bis

///////////////////////////////////////////////////////////////////////////
// Arduino Cameriere
// 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)
 
// TAGS
char* tagA = "21003BDAE6"; // admin
char* tagH = "21003BC77C"; // homebase
 
// andra' riletto a step 10
char* tags = "21003BE7CF21003BA8CF21003BDA9D21003BF50121003BC43E21003BD57621003B91EA21003BDAE6";
 
// 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 int IRcodes_number[] = {16724685, 16740495, 16757325, 16773645, 16741005, 16764975, 16732845, 16716525};
const int IRcodes_len = 8;
const int IRcodes_ok = 16755285;
const int IRcodes_exit = 16718055;
const int IRcodes_sx = 16769565;
const int IRcodes_dx = 16754775;
 
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_PIN = 3; // motore
 
char tagString[11];
char tagCustomer[11];
 
// costanti ognuna delle quali definisce uno stato
const int STOP = 0;
const int ADMINCARICO = 1;
const int INMOTOCONSEGNA = 2;
const int STOPFORCONSEGNA = 3;
const int INMOTORIENTRO = 4;
 
// stato dell'automa
int currentState = STOP;
 
// stato delle attivazioni
boolean engine_state = false;
//boolean led1 = false;
//boolean led2 = false;
// etc...
 
////////////////////////////////////////////////
////////////////////////////////////////////////
void setup()
{
    // IR sensor
    Serial.begin(9600);
    irrecv.enableIRIn(); // Start the receiver
 
    // TAG reader
    pinMode(TAGREADER_RESET_PIN, OUTPUT);
    digitalWrite(TAGREADER_RESET_PIN, HIGH);
    tagReader_reset();
}
 
////////////////////////////////////////////////
void loop() {
    //selectLineOne(); // non va
    lcd_clear();
 
    // ciclo di lettura di tutti gli ingressi (IR e RFID)
    // legge e memorizza in un buffer (globale)
 
    // IR
    if (ir_read()){
    	Serial.print("i:");
    	Serial.print(results.value);
        Serial.print(",");
    }
 
    // TAG
    tagReader_read();
    if(strlen(tagString) > 1){
      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);
    switch (currentState) {
      case STOP:
        state_STOP();
        break;
      case ADMINCARICO:
        state_ADMINCARICO();
        break;
      case INMOTOCONSEGNA:
        state_INMOTOCONSEGNA();
        break;
      case STOPFORCONSEGNA:
        state_STOPFORCONSEGNA();
        break;
      case INMOTORIENTRO:
        state_INMOTORIENTRO();
        break;
    }
 
    // ciclo di attivazione (motori, luci, etc.)
    digitalWrite(ENGINE_PIN, engine_state);
    Serial.print("t1=");
    Serial.print(t1);
    Serial.print("t2=");
    Serial.print(t2);
    Serial.print(" ");
    Serial.print(tagCustomer);
    Serial.print(" ");
    Serial.print(results.value);
    // per "debugging", cosi' si vede se fa qualcosa
    //    Serial.print(",ms:");
    //    Serial.print(millis());
    Serial.println();
    tagReader_reset();
    delay(1000);
}
 
 
////////////////////////////////////////////////
////////////////////////////////////////////////
//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: motore fermo, modalita' controlla RFIDTAG (se admin goto 1)
1) ADMINCARICO: motore fermo, ****attesa IR (se OK su IR goto 2)
2) INMOTOCONSEGNA: motore acceso, controlla RFIDTAG (se customer corretto goto 3)
3) STOPFORSECONSEGNA: motore fermo, delay e goto 4
4) INMOTORIENTRO: motore acceso, controllo RFIDTAG (se admin goto 1, se HOMEBASE goto 0)
*/
 
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;
    tagReader_clearTag(tagCustomer);
 
    // fare lettura complessa da IR (serve nr customer e OK)
    if (results.value != 0)    
    {
        // scorre la lista degli input mappati dall'IR
        for(int i = 0; i < IRcodes_len; i++){
          // trova l'indice del codice corrispondente al tag
          if(IRcodes_number[i] == results.value){
            t1=true;
            // copia il tag corrispondente all'indice nel tag customer
            for(int j = 0; j < 11; j++){
              t2=true;
              tagCustomer[j] = tags[(i * 10) + j];
            }
          }
        }
        // accende il motore, cambia stato e va in consegna
     	engine_state = true;
        currentState = INMOTOCONSEGNA;
    }
 }
 
void state_INMOTOCONSEGNA() {
    engine_state = true;
    if (tagReader_compareTag(tagCustomer, tagString))
    {
	engine_state = false;
        currentState = STOPFORCONSEGNA;
    }
}
 
void state_STOPFORCONSEGNA() {
    engine_state = false;
    delay(2000);
    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 and sets the 
// tagString to NULL.
void tagReader_reset() 
{
    digitalWrite(TAGREADER_RESET_PIN, LOW);
    digitalWrite(TAGREADER_RESET_PIN, HIGH);
    // Output ID strig set to NULL
    tagReader_clearTag(tagString);
    delay(150);
}
 
// Reading ID-12 Output
// 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);
}
 
///////////////////////////////////////////////////////////////////////////
/// 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(int ir_code)
{
  /* "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;
  }
  /* return 9999 if key code not found */
  return 9999;
}
 
// Gestione lettura IR
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(10);
}
 
/*
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);
}
*/

16 giugno 2011

///////////////////////////////////////////////////////////////////////////
// Arduino Cameriere
// 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)
 
// TAGS
char* tagA = "21003BDAE6"; // admin
char* tagH = "21003BC77C"; // homebase
 
// andra' riletto a step 10
char* tags = "21003BE7CF21003BA8CF21003BDA9D21003BF50121003BC43E21003BD57621003B91EA21003BDAE6";
 
// IR
const int IR_PIN = 11; // infrarosso
decode_results results; // struttura dati per IR
IRrecv irrecv(IR_PIN); // setup libreria IR
 
// andra' riletto a step 6
char* IRcodes_number = "FFB04FFF32CDFF708FFFB24DFFF20DFF728DFFD02FFF52ADFF12EDFF50AF";
 
const char* IRcodes_ok = "FFAA55";
const char* IRcodes_exit = "FF18E7";
const char* IRcodes_sx = "FFE21D";
const char* IRcodes_dx = "FFA857";
 
/*
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_PIN = 3; // motore
 
char tagString[11];
char tagCustomer[11];
 
// costanti ognuna delle quali definisce uno stato
const int STOP = 0;
const int ADMINCARICO = 1;
const int INMOTOCONSEGNA = 2;
const int STOPFORCONSEGNA = 3;
const int INMOTORIENTRO = 4;
 
// stato dell'automa
int currentState = STOP;
 
// stato delle attivazioni
boolean engine_state = false;
//boolean led1 = false;
//boolean led2 = false;
// etc...
 
////////////////////////////////////////////////
////////////////////////////////////////////////
void setup()
{
 
// POI RIMOUOVERE, SOLO PER TEST!!! 
 // strcpy(tagCustomer,tags[20]);
 
    // IR sensor
    Serial.begin(9600);
    irrecv.enableIRIn(); // Start the receiver
 
    // TAG reader
    pinMode(TAGREADER_RESET_PIN, OUTPUT);
    digitalWrite(TAGREADER_RESET_PIN, HIGH);
    tagReader_reset();
 
    // non serve piu'
    //attachInterrupt(STOP_INTERRUPT, stop_received, LOW); // pin 2
}
 
////////////////////////////////////////////////
void loop() {
    //selectLineOne(); // non va
    lcd_clear();
 
    // ciclo di lettura di tutti gli ingressi (IR e RFID)
    // legge e memorizza in un buffer (globale)
 
    // IR
    if (ir_read()){
    	Serial.print("i:");
    	Serial.print(results.value, HEX);
    }
 
    // TAG
    tagReader_read();
    if(tagString[0] != 0){
      Serial.print(",t:");
      Serial.print(tagString);
    }
    tagReader_reset();
 
    // AUTOMA
    // eventuale cambio stato (sia stato dell'automa sia stato di attivazione motori e luci etc.)
    Serial.print(",s:");
    Serial.print(currentState);
    switch (currentState) {
      case STOP:
        state_STOP();
        break;
      case ADMINCARICO:
        state_ADMINCARICO();
        break;
      case INMOTOCONSEGNA:
        state_INMOTOCONSEGNA();
        break;
      case STOPFORCONSEGNA:
        state_STOPFORCONSEGNA();
        break;
      case INMOTORIENTRO:
        state_INMOTORIENTRO();
        break;
    }
 
    // ciclo di attivazione (motori, luci, etc.)
    digitalWrite(ENGINE_PIN, engine_state);
 
 
    // per "debugging", cosi' si vede se fa qualcosa
    //    Serial.print(",ms:");
    //    Serial.print(millis());
    delay(2000);
}
 
 
////////////////////////////////////////////////
////////////////////////////////////////////////
//LIBRERIE & FUNZIONI
 
/* 
* 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(char* ir_code)
{
  /* "i" is the base of each mapped key code on the array */
  for (int i = 0; i*6 < strlen(IRcodes_number); i++){ 
    /* if key code is mapped return tag index */
    if(string_compare(ir_code, IRcodes_number, i)) return i;
   }
  /* return 9999 if key code not found */
  return 9999;
}
 
/* 
* 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;
}
 
/* 
* Compare two values to see if same,
* if strcmp not working 100% we do this...
*/
boolean tagReader_compareTag(char* one, char* two) {
	return string_compare(one, two, 0);
}
 
///////////////////////////////////////////////////////////////////////////
// AUTOMA
/*
0) STOP: motore fermo, modalita' controlla RFIDTAG (se admin goto 1)
1) ADMINCARICO: motore fermo, ****attesa IR (se OK su IR goto 2)
2) INMOTOCONSEGNA: motore acceso, controlla RFIDTAG (se customer corretto goto 3)
3) STOPFORSECONSEGNA: motore fermo, delay e goto 4
4) INMOTORIENTRO: motore acceso, controllo RFIDTAG (se admin goto 1, se HOMEBASE goto 0)
*/
 
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 (tutto ok)
    delay(500);
    {
     	engine_state = true;
        currentState = INMOTOCONSEGNA;
    }
 }
 
void state_INMOTOCONSEGNA() {
    engine_state = true;
    if (tagReader_compareTag(tagCustomer, tagString))
    {
	engine_state = false;
        currentState = STOPFORCONSEGNA;
    }
}
 
void state_STOPFORCONSEGNA() {
    engine_state = false;
    delay(2000);
    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;
 }
 
///////////////////////////////////////////////////////////////////////////
// LCD (verificare se questi codici funzionano con lo sparkfun)
 
/*
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_clear() {
    Serial.print(0xFE, BYTE);   //command flag
    Serial.print(0x01, BYTE);   //clear command.
    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);
}
*/
 
 
//////////////////////////////////////////////////////////
// TAG
//Reset the RFID reader to read again.
void tagReader_reset() {
    digitalWrite(TAGREADER_RESET_PIN, LOW);
    digitalWrite(TAGREADER_RESET_PIN, HIGH);
    // Output ID strig set to NULL
    tagReader_clearTag(tagString);
    delay(150);
}
 
// Reading ID-12 Output
// 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;
    }
}
 
 
///////////////////////////////////////////////////////////////////////////
/// IR
 
// Gestione lettura IR
boolean ir_read()
{
    boolean out = false;
    if (irrecv.decode(&results)) {
        out = true;
        irrecv.resume(); // Receive the next value
    }
    return out;
}

15 giugno 2011

///////////////////////////////////////////////////////////////////////////
// Arduino Cameriere
// 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)
 
// TAGS
char* tagA = "21003BDAE6"; // admin
char* tagH = "21003BC77C"; // homebase
 
// andra' riletto a step 10
char* tags[]={"21003BE7CF", 
              "21003BA8CF", 
              "21003BDA9D",
              "21003BF501", 
              "21003BC43E", 
              "21003BD576", 
              "21003B91EA", 
              "21003BDAE6"};
 
// IR
const int IR_PIN = 11; // infrarosso
decode_results results; // struttura dati per IR
IRrecv irrecv(IR_PIN); // setup libreria IR
 
// andra' riletto a step 6
const char* IRcodes_number[] ={"FFB04F", 
                               "FF32CD", 
                               "FF708F", 
                               "FFB24D", 
                               "FFF20D", 
                               "FF728D", 
                               "FFD02F", 
                               "FF52AD", 
                               "FF12ED", 
                               "FF50AF"};
 
const char* IRcodes_ok = "FFAA55";
const char* IRcodes_exit = "FF18E7";
const char* IRcodes_sx = "FFE21D";
const char* IRcodes_dx = "FFA857";
 
/*
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_PIN = 3; // motore
 
char tagString[11];
char tagCustomer[11];
 
// costanti ognuna delle quali definisce uno stato
const int STOP = 0;
const int ADMINCARICO = 1;
const int INMOTOCONSEGNA = 2;
const int STOPFORCONSEGNA = 3;
const int INMOTORIENTRO = 4;
 
// stato dell'automa
int currentState = STOP;
 
// stato delle attivazioni
boolean engine_state = false;
//boolean led1 = false;
//boolean led2 = false;
// etc...
 
////////////////////////////////////////////////
////////////////////////////////////////////////
void setup()
{
 
// POI RIMOUOVERE, SOLO PER TEST!!! 
 // strcpy(tagCustomer,tags[20]);
 
    // IR sensor
    Serial.begin(9600);
    irrecv.enableIRIn(); // Start the receiver
 
    // TAG reader
    tagReader_reset();
 
    // non serve piu'
    //attachInterrupt(STOP_INTERRUPT, stop_received, LOW); // pin 2
}
 
////////////////////////////////////////////////
void loop() {
    //selectLineOne(); // non va
    lcd_clear();
 
// ciclo di lettura di tutti gli ingressi (IR e RFID)
// legge e memorizza in un buffer (globale)
 
// IR
    if (ir_read()){
    	Serial.print("i:");
    	Serial.print(results.value, HEX);
    }
 
// TOCHECK  non legge piu' i tag, come mai!?!?!?
 
// TAG
//   tagString = tagReader_read();
    tagReader_read();
    Serial.print(",t:");
    Serial.print(tagString);
    tagReader_reset();
 
// AUTOMA
// eventuale cambio stato (sia stato dell'automa sia stato di attivazione motori e luci etc.)
    Serial.print(",s:");
    Serial.print(currentState);
    switch (currentState) {
    case STOP:
        state_STOP();
    case ADMINCARICO:
        state_ADMINCARICO();
    case INMOTOCONSEGNA:
        state_INMOTOCONSEGNA();
    case STOPFORCONSEGNA:
        state_STOPFORCONSEGNA();
    case INMOTORIENTRO:
        state_INMOTORIENTRO();
    }
 
// ciclo di attivazione (motori, luci, etc.)
    digitalWrite(ENGINE_PIN, engine_state);
 
 
// per "debugging", cosi' si vede se fa qualcosa
    Serial.print(",ms:");
    Serial.print(millis());
    delay(2000);
}
 
 
 
 
 
 
 
 
////////////////////////////////////////////////
////////////////////////////////////////////////
//LIBRERIE & FUNZIONI
 
/* 
* 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(char* ir_code)
{
  /* "i" is the base of each mapped key code on the array */
  for (int i = 0; i*6 < strlen(IRcodes_number), i++){ 
    /* if key code is mapped return tag index */
    if(string_compare(ir_code, IRcodes_number, i*6)) return i;
   }
  /* return 9999 if key code not found */
  return 9999;
}
 
 
/* 
* 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;
}
 
/* 
* Compare two values to see if same,
* if strcmp not working 100% we do this...
*/
boolean tagReader_compareTag(char* one, char* two) {
	return string_compare(one, two, 0);
}
 
///////////////////////////////////////////////////////////////////////////
// AUTOMA
/*
0) STOP: motore fermo, modalita' controlla RFIDTAG (se admin goto 1)
1) ADMINCARICO: motore fermo, ****attesa IR (se OK su IR goto 2)
2) INMOTOCONSEGNA: motore acceso, controlla RFIDTAG (se customer corretto goto 3)
3) STOPFORSECONSEGNA: motore fermo, delay e goto 4
4) INMOTORIENTRO: motore acceso, controllo RFIDTAG (se admin goto 1, se HOMEBASE goto 0)
*/
 
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 (tutto ok)
    delay(500);
    {
     	engine_state = true;
        currentState = INMOTOCONSEGNA;
    }
 }
 
void state_INMOTOCONSEGNA() {
    engine_state = true;
    if (tagReader_compareTag(tagCustomer, tagString))
    {
	engine_state = false;
        currentState = STOPFORCONSEGNA;
    }
}
 
void state_STOPFORCONSEGNA() {
    engine_state = false;
    delay(2000);
    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;
 }
 
///////////////////////////////////////////////////////////////////////////
// LCD (verificare se questi codici funzionano con lo sparkfun)
 
/*
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_clear() {
    Serial.print(0xFE, BYTE);   //command flag
    Serial.print(0x01, BYTE);   //clear command.
    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);
}
*/
 
 
//////////////////////////////////////////////////////////
// TAG
//Reset the RFID reader to read again.
void tagReader_reset() {
    digitalWrite(TAGREADER_RESET_PIN, LOW);
    digitalWrite(TAGREADER_RESET_PIN, HIGH);
    // Output ID strig set to NULL
    tagReader_clearTag(tagString);
    delay(150);
}
 
// Reading ID-12 Output
// 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;
    }
}
 
 
///////////////////////////////////////////////////////////////////////////
/// IR
 
// Gestione lettura IR
boolean ir_read()
{
    boolean out = false;
    if (irrecv.decode(&results)) {
        out = true;
        irrecv.resume(); // Receive the next value
    }
    return out;
}

9 giugno 2011

///////////////////////////////////////////////////////////////////////////
// Arduino Cameriere
// 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)
 
int IR_PIN = 11; // infrarosso
decode_results results; // struttura dati per IR
IRrecv irrecv(IR_PIN); // setup libreria IR
 
int STOP_PIN = 2; // paraurti  PIN2 per interrupt 0
int STOP_INTERRUPT = 0; // paraurti  PIN2 per interrupt 0
 
int EMPTY_PIN = TBD; // sensore vuoto/pieno
 
int LCD_PIN = 1; // uscita seriale lcd (TX)
 
int TAGREADER_PIN = 0; // ingresso seriale ID-12 (RX)
int TAGREADER-RESET_PIN = 13; // reset lettore ID-12
 
int ENGINE_PIN = TBD; // motore
 
 
 
 
//MAIN
 
// ONCE
void setup()
{
  Serial.begin(9600);
  irrecv.enableIRIn(); // Start the receiver
  pinMode(TAGREADER-RESET_PIN, OUTPUT);
  digitalWrite(TAGREADER-RESET_PIN, HIGH);
 
  attachInterrupt(STOP_INTERRUPT, stop_received, LOW); // pin 2
  //sistemare globals
}
 
// LOOP
 
void loop() {
  lcd_clear(); 
 
  //selectLineOne();
 
  Serial.print("i:");
 
  // trasformare in funzione
  if (irrecv.decode(&results)) {
    Serial.print(results.value, HEX);
//    Serial.print(results.value, DEC);
    irrecv.resume(); // Receive the next value
  }
 
 
  char[13] tagString=tag_read();
  Serial.print(",t:");
  Serial.print(tagString);
  resetReader(); //reset the RFID reader
 
  Serial.print(",ms:");
  Serial.print(millis());
  delay(1000);
}
 
 
 
 
 
//LIBRERIE
 
 
// LCD (verificare se questi codici funzionano con lo sparkfun)
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_clear(){
   Serial.print(0xFE, BYTE);   //command flag
   Serial.print(0x01, BYTE);   //clear command.
   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);
}
 
// TAG
void tag_resetReader(){
 
//Reset the RFID reader to read again.
 
  digitalWrite(TAGREADER-RESET_PIN, LOW);
  digitalWrite(TAGREADER-RESET_PIN, HIGH);
  delay(150);
}
 
//////////////////////////////////////////////
 
// Reading ID-12 Output
// One frame is not enough to read 64bit of ID
 
//////////////////////////////////////////////
char[] tag_read(){
  // ID read string from TAG
  char tagString[8];
  // Index byte read
  int index = 0;
  // Data structure state flag
  boolean reading = false;
 
  // Output ID strig set to NULL
  clearTag(tagString);
 
  // (index < 18) = 5bytes data + 1byte checksum + 3bytes data
  //              = 2 Frames (check data block from second frame)
  while(Serial.available() && index < 18){
    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){
      // If needed add an appropriate checksum function 
      // IF (index == 6 || index == 12) THEN checksum()
      if (index > 6) tagString[index-1] = readByte;      
      tagString[index] = readByte;
      index++;
    }
  }
  return tagString;
}
 
/////////////////////////////////////////////////////
 
//Clear the char array by filling with null - ASCII 0
 
/////////////////////////////////////////////////////
void clearTag(char tag[]){
 
  for(int i = 0; i < strlen(tag); i++){
    tag[i] = 0;
  }
}
 
///////////////////////////////////////////////////
 
// Compare two value to see if same,
// strcmp not working 100% so we do this
 
///////////////////////////////////////////////////
boolean compareTag(char one[], char two[]){
 
  // If empty or not equal length then exit 0
  if(strlen(one) == 0 || strlen(one) != strlen(two)) return false; 
 
  // Compare tags
  for(int i = 0; i < strlen(one); i++){
    // If not equal then exit 0
    if(one[i] != two[i]) return false;
  }
 
  // No mismatches, exit 1
  return true; 
}
 
///////////////////////////////////////////////////////////////////////////
/// LUCI
 
///////////////////////////////////////////////////////////////////////////
/// IR
 
///////////////////////////////////////////////////////////////////////////
/// MOTORE
 
void engine_start(){
  pinMode(ENGINE_PIN, OUTPUT);
  digitalWrite(ENGINE_PIN, HIGH);
}
 
void engine_stop(){
  pinMode(ENGINE_PIN, OUTPUT);
  digitalWrite(ENGINE_PIN, LOW);
}
 
///////////////////////////////////////////////////////////////////////////
/// STOP (paraurti) potreebbe essere fatto su interrupt
void stop_received(){
  engine_stop();
}
 
///////////////////////////////////////////////////////////////////////////
/// MUSICA
 
///////////////////////////////////////////////////////////////////////////
/// TAGDB
 
 
///////////////////////////////////////////////////////////////////////////
/// GABBIA (not yet implemented)
 
 
 
// non so se serve, fare check
void serCommand(){   //a general function to call the command flag for issuing all other commands   
  Serial.print(0xFE, BYTE);
}
//costanti ognuna delle quali definisce uno stato
	int STOP = 0;
	int ADMIN = 1;
	int MOTOCONSEGNA = 2;
	int CONSEGNA = 3;
	int MOTORIENTRO = 4;
 
	int currentState = STOP;
 
// Variabile stato corrente che cambia in funzione dello switch
loop {
	switch(currentState){
		case STOP:
			stop();
		case ADMIN:
			admin();
		case MOTOCONSEGNA:
			motoConsegna();
		case CONSEGNA:
			consegna();
		case MOTORIENTRO:
			motoRientro();
		default:
			stop();
	}
        tag_resetReader();
}
 
//implementare funzioni stop motore
void stop() {
	if (RFID_ADMIN)
                // inserisce in currentState lo stato prossimo
		currentState = ADMIN 
}
 
//implementare funzioni di admin 
void admin() {
	if (IR_START)
		currentState = MOTOCONSEGNA
}
 
//implementare funzioni del movimento per la consegna
void motoConsegna() {	
	if(STOP_RFID)
		currentState = CONSEGNA
}
 
//implementare la funzione di consegna e controllo consegna avvenuta
void Consegna() {
	if (CONSEGNA_TRUE)
		currentState = MOTORIENTRA
	else 
		currentState = MOTOCONSEGNA
}
 
//implementare movimento e controllo di rientro		
void motoRientro() {
	if(RIENTRO_TRUE)
		currentState = STOP //torna allo stop
}
pub/arduino/codice_sorgente_arducameriere.txt · Last modified: 2011/06/18 16:56 by atrent