Table of Contents

ArduSlave

… poi abbiamo scoperto l'esistenza di firmata m(

Libreria per comandare Arduino via comandi "Hayes"-like

Stato

Quasi completo (stiamo facendo prove per migliorare la ricezione via seriale), il codice è migliorabilissimo ;)

Ora vorremmo semplificarlo (rispetto al sorgente qui sotto) e passare alla lettura dello stream byteBybyte senza passare da un buffer (MdT like)

Codice

Albero stringhe di comando
|
|-P(inmode) [forse non serve, viene sempre chiamato un pinmode per ogni out]
|      \
|       |-I-pinNumberXX [setta in input]
|       |-O-pinNumberXX [setta in output]
|
|-D(igital)
|      \
|       |-I-pinNumberXX [ritorna valore]
|       |-I-A [stampa tutti i valori]
|       |-O-pinNumberXX-H/L
|       |-O-A-H/L [tutti su o giu']
|
|-A(nalog)
|      \
|       |-I-pinNumberXX [ritorna valore]
|       |-O-pinNumberXX-valueXXX
|       |-I-A [stampa tutti i valori]
|
|-X(eXtended)
|      \
|       |-A-pinNumberXX-pinNumberXX-valueXXX [setta DUE pin contemporaneamente]
|       |-D-pinNumberXX-pinNumberXX-H/L [setta DUE pin contemporaneamente]
|
|-V(ersion) [ritorna valore]
|
|-NP(umber of pins)  [ritorna valore]
|
|-T(est)  [alza e abbassa tutti i pin]

RC1

/**
 * (ordine alfabetico)
 * Copyright 2012 Luca "Palmino" Palmulli <luca.palmulli@gmail.com>
 * Copyright 2012 Matteo Pessina <matteo.pessina3@studenti.unimi.it>
 * Copyright 2012 Andrea "Piso" Pisoni <andreapiso@gmail.com>
 * Copyright 2012 Simone "Pizzy" Pizzimenti <pizzy90@gmail.com>
 * Copyright 2012 Andrea "atrent" Trentini <andrea.trentini@unimi.it>
 *
 * This file is (the lib) part of ArduSlave.
 *
 * ArduSlave 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.
 *
 * Arduslave 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 Foobar.  If not, see <http://www.gnu.org/licenses/>.
 *
 * 	@author tutti

MASTER REF per il "linguaggetto" !!!

Attenzione ad adattare MAXCOMMANDLENGTH se si aggiungono comandi lunghi

Albero stringhe di comando
|
|-P(inmode) [forse non serve, viene sempre chiamato un pinmode per ogni out]
|      \
|       |-I-pinNumberXX [setta in input]
|       |-O-pinNumberXX [setta in output]
|
|-D(igital)
|      \
|       |-I-pinNumberXX [ritorna valore]
|       |-I-A [stampa tutti i valori]
|       |-O-pinNumberXX-H/L
|       |-O-A-H/L [tutti su o giu']
|
|-A(nalog)
|      \
|       |-I-pinNumberXX [ritorna valore]
|       |-O-pinNumberXX-valueXXX
|       |-I-A [stampa tutti i valori]
|
|-X(eXtended)
|      \
|       |-A-pinNumberXX-pinNumberXX-valueXXX [setta DUE pin contemporaneamente]
|       |-D-pinNumberXX-pinNumberXX-H/L [setta DUE pin contemporaneamente]
|
|-V(ersion) [ritorna valore]
|
|-NP(umber of pins)  [ritorna valore]
|
|-T(est)  [alza e abbassa tutti i pin]
|
*
* TODO aggiungere "sensori" di trigger degli input digitali in modo da rendere
* arduslave non piu' totalmente passivo ma dotato di iniziativa autonoma?
*
* esiste modo di attivare qualche interrupt certo? (verificare su arduino.cc)
* altrimenti memorizzare una stringa di bit e verificare differenze in fondo allo swiccione
*
* TODO ripulire man mano il codice
*
*/

/////////////////////////////////////////////////////////////////
#define SERIALFREQ 115200

/////////////////////////////////////////////////////////////////
#define ENDCHR '#'

/////////////////////////////////////////////////////////////////
#define MAXCOMMANDLENGTH 12
#define LOOPDELAY 0
#define SERIALDELAY 10
#define TESTDELAY 50

/////////////////////////////////////////////////////////////////
// valori alti per test con interazione umana, bassi in produzione
#define MAXWAIT 1000

///////////////////////////////////////////////
/* per ArduinoUNO */
#define MINPIN 0		//min pin
#define MAXPIN 13		//max pin
///////////////////////////////////////////////

char command[MAXCOMMANDLENGTH] = "";
int pin_value;
int pin_value_more;
int level_value;

/***********************************************************************
 * setup ufficiale dell'Arduino
 */
void slave_setup()
{
    // init seriale
    Serial.begin(SERIALFREQ);
    Serial.println("End of slave lib setup...");
}

/***********************************************************************/
void slave_loop()
{
    // legge da seriale
    readLine2();

    //switchone
    switch(command[0])    // brancha sul primo carattere del comando (prefisso)
    {
    case 'P': //PINMODE
        goP();
        break;
    case 'D': //DIGITAL
        goD();
        break;
    case 'A': //ANALOG
        goA();
        break;
    case 'X': //EXTENDED OUTPUT (doppio pin)
        goX();
        break;
        /*
            case 'V': // V(ersion)? //TODO
                break;
        */
    case 'T': // test
        goT();
        break;
    case 'N':
        goN();
        break;
    default:
        Serial.println("NO MATCH FOUND");//return errore
        break;
    }

    // pulisce stringa
		memset(command, 0, MAXCOMMANDLENGTH);

    delay(LOOPDELAY); // TODO verificare un giusto delay
}


/**********************************
 * digital
 */
void digital_output_all_h()
{
    for(int i=MINPIN; i<=MAXPIN; i++)
    {
        digital_output_h(i);
    }
}

void digital_output_all_l()
{
    for(int i=MINPIN; i<=MAXPIN; i++)
    {
        digital_output_l(i);
    }
}

void digital_output_h(int pin)
{
    pinMode(pin, OUTPUT);
    digitalWrite(pin, HIGH);
}

void digital_output_l(int pin)
{
    pinMode(pin, OUTPUT);
    digitalWrite(pin, LOW);
}

void digital_input(int pin)
{
    pinMode(pin, INPUT);
    Serial.println(digitalRead(pin));
}

void digital_input_all()
{
    for(int i=MINPIN; i<=MAXPIN; i++)
    {
        digital_input(i);
        //Serial.println();
    }
}

/**********************************
 * analog
 */
void analog_output(int pin, int value)
{
    pinMode(pin, OUTPUT);
    analogWrite(pin, value);
}

void analog_input(int pin)
{
    pinMode(pin, INPUT);
    Serial.print(pin);
    Serial.print(":");
    Serial.println(analogRead(pin));
}

void analog_input_all()
{
    for(int i=MINPIN; i<=MAXPIN; i++)
    {
        analog_input(i);
        //Serial.println();
    }
}

/**
 * crea l'int da una stringa di 3 caratteri
 */
int chars2i(char centinaia, char decina, char unita)
{
    return (centinaia-'0')*100 + (decina-'0')*10 + (unita - '0');
}

void n_pins()
{
    Serial.print("MINPIN:");
    Serial.print(MINPIN);
    Serial.print("\nMAXPIN:");
    Serial.println(MAXPIN);
}

/**
 legge da seriale e scrive in command
 (andava cambiata perche' cosi' si perdevano caratteri nel senso che se uno scriveva comandi con calma la stringa ne usciva incompleta)
 ora semi-bloccante, con timeout

void readLine()
{
    // loop "infinito" (con timeout)
    int esce=MAXWAIT;
    for(int i=0; i<MAXCOMMANDLENGTH;)
    {
        if(Serial.available()>0)
        {
            command[i]=Serial.read();
            //Serial.print("I received: ");
            Serial.print(command[i]);
            if(command[i]=='\n') break; //TODO platform dependent?
            i++;
        }
        delay(SERIALDELAY); // TODO verificare un giusto delay
        esce=esce-SERIALDELAY;
        if(esce==0) break;
    }
    // svuotare buffer se stringa troppo lunga?
}
*/

void readLine2()
{
		char c;
		int i=0;
		while((c = Serial.read())!=ENDCHR)
		{
				if (c!=-1) 
				{
						command[i]=c;
						i++;
				}
		}
}


// eventualmente pensare carattere NOP, es. #
void resetLine()
{
    for(int i=0; i<MAXCOMMANDLENGTH; i++)
    {
        command[i]=0;
    }
}



/**********************************
 * gestione comandi
 */

void goP()
{
    switch(command[1])
    {
    case 'O':  //output
        pin_value = chars2i('0', command[2],command[3]); // TODO: e se la stringa e' piu' corta?
        if((pin_value>=MINPIN) && (pin_value<=MAXPIN))
        {
            pinMode(pin_value,OUTPUT);
            Serial.println("'PO' OK");//return OK
        }
        break;
    case 'I': //input
        pin_value = chars2i('0', command[2],command[3]); // TODO: e se la stringa e' piu' corta?
        if((pin_value>=MINPIN) && (pin_value<=MAXPIN))
        {
            pinMode(pin_value,INPUT);
            Serial.println("'PI' OK");//return OK
        }
        break;
    default:
        Serial.println("'P' incomplete");//return errore
        break;
    }
}

void goD()
{
    switch(command[1])
    {
    case 'O':  //output
        if(command[2]=='A')
        {
            if(command[3]=='H') digital_output_all_h();
            if(command[3]=='L') digital_output_all_l();
        }
        else
        {
            pin_value = chars2i('0', command[2],command[3]); // TODO: e se la stringa e' piu' corta?
            if((pin_value>=MINPIN) && (pin_value<=MAXPIN))
            {
                if(command[4]=='H') digital_output_h(pin_value);//esegui il comando DOpinH
                if(command[4]=='L') digital_output_l(pin_value);//esegui il comando DOpinL
            }
        }
        Serial.println("'DO' ~OK (parziale)");//return ~OK
        break;
    case 'I': //input
        if(command[2]=='A')
        {
            // stampa stringa con tutti, es. 011001001
            digital_input_all();
        }
        else
        {
            pin_value = chars2i('0', command[2],command[3]); // TODO: e se la stringa e' piu' corta?
            if((pin_value>=MINPIN) && (pin_value<=MAXPIN))
            {
                digital_input(pin_value);// esegui il comando DIpin
            }
        }
        Serial.println("'DI' ~OK (parziale)");//return ~OK
        break;
    default:
        Serial.println("'D' incomplete");//return errore
        break;
    }
}


void goA()
{
    pin_value = chars2i('0', command[2],command[3]);
    if((pin_value<MINPIN) || (pin_value>MAXPIN)) return;

    switch(command[1])
    {
        //output
    case 'O':
        level_value = chars2i(command[4],command[5], command[6]);
        if((level_value>=0) && (level_value<=255))
        {
            analog_output(pin_value, level_value);//esegui il comando AOpinvalue
            Serial.println("'AO' OK ");//return OK
        }
        else
            Serial.println("value out of range");//return errore
        break;
        //input
    case 'I':
        if(command[2]=='A')
            analog_input_all();
        else
            analog_input(pin_value);//esegui il comando AOpin
        break;
    default:
        Serial.println("'A' incomplete");//return errore
        break;
    }
}

void goX()
{
    pin_value = chars2i('0', command[2],command[3]);
    pin_value_more = chars2i('0', command[4],command[5]);
    // TODO check espressione booleana!!!
    if(
        (pin_value<MINPIN) || (pin_value>MAXPIN)
        ||
        (pin_value_more<MINPIN) || (pin_value_more>MAXPIN)
    )
    {
        Serial.println("'X*' pin error");//return errore
        return;
    }

    switch(command[1])
    {
        //digital
    case 'D':
        if(command[6]=='H')
        {
            digital_output_h(pin_value);
            digital_output_h(pin_value_more);
        }
        if(command[6]=='L')
        {
            digital_output_l(pin_value);
            digital_output_l(pin_value_more);
        }
        break;
        //analog
    case 'A':
        level_value = chars2i(command[6],command[7], command[8]);
        if((level_value>=0) && (level_value<=255))
        {
            analog_output(pin_value, level_value);
            analog_output(pin_value_more, level_value);
            Serial.println("'XA' OK ");//return OK
        }
        break;
    default:
        Serial.println("'XD' incomplete");//return errore
        break;
    }
}

void goT()
{
    // test
    for(int quante=0; quante<3; quante++)
    {
        for(int i=MINPIN; i<=MAXPIN; i++)
        {
            for(int liv=0; liv<255; liv+=30)
            {
                //digital_output_h(i);
                analog_output(i,liv);
                delay(TESTDELAY);
                digital_output_l(i);
                Serial.print("quante:");
                Serial.print(quante);
                Serial.print(", pin:");
                Serial.print(i);
                Serial.print(", liv:");
                Serial.println(liv);
            }
        }
    }
}

void goN()
{
    if(command[1] == 'P')
    {
        n_pins();
    }
}
pub/arduino/arduslave.txt · Last modified: 2013/04/08 08:29 by atrent
CC Attribution-Share Alike 4.0 International
Driven by DokuWiki Recent changes RSS feed Valid CSS Valid XHTML 1.0