arduino uno + wifly newbie

Ciao, oggi per la prima volta inizio la programmazione su arduino. In particolare sto lavorando su un modulo wifly e un ipad. per la parte ipad nessun problema, ma non ho mai lavorato con arduino e mi sento un poì niubbo...

Ho iniziato con un codice datomi da un amico ma non è esattamente il max, volevo sapere se potevate darmi qualche consiglio sul codice oppure link che mi possano indirizzare su questo mondo..

#include "WiFly.h"
#include "string.h"
#include "Servo.h"
//#include "Credentials.h"
Servo myservo5;
Servo myservo6;
int pos5=90;
int pos6=90;

void setup() {

 Serial.begin(9600);
 SpiSerial.begin();

 myservo5.attach(5);
 myservo6.attach(6);
 pinMode(7, OUTPUT);
 pinMode(8, OUTPUT);
 pinMode(3, OUTPUT);
 digitalWrite(7,LOW);
 digitalWrite(8,LOW);
 digitalWrite(3,LOW);

}

String myString=0;
String seriale=0;
byte myByte=0;
int realData=0;
boolean dataReceiving = false;
int dataCounter = 0;
int ok=0;
boolean led2 = false;


void loop() 
{

  while(SpiSerial.available() >0) 
  {
     dataReceiving = true;
     myByte = SpiSerial.read();
     myString = myByte;
     Serial.print(myString);
     //dataCounter =dataCounte 1;

   if(Serial.available()) 
   { // Outgoing data
     SpiSerial.print(Serial.read(), BYTE);
   }

    if (myString=="+")
    {   //se connesso accendi LED Verde
       //digitalWrite(7,HIGH);
       digitalWrite(8,LOW);
       myservo5.write(pos5);
       myservo6.write(pos6);
       ok=ok+1;

   }

   if(ok<1)
   {
     digitalWrite(7,LOW);

   }

   if (myString=="-"){  //se non connesso accendi LED Rosso
   digitalWrite(8,HIGH); //accendi LED rosso
   digitalWrite(7,LOW);
   myservo5.write(pos5);
   myservo6.write(pos6);

   }

     if (myString=="0")
     {
       if(led2)
       {
         digitalWrite(3,LOW);
         led2 = false;
       }
       else
       {
         digitalWrite(3,HIGH);
         led2 = true;
         
       }
       SpiSerial.print("0");
     }
     if (myString=="10")
     {
       if(led2)
       {
         digitalWrite(7,LOW);
         led2 = false;
       }
       else
       {
         digitalWrite(7,HIGH);
         led2 = true;
         
       }
       SpiSerial.print("10");
     }
}
}

praticamente per il momento vorrei che se la stringa letta è 0 accenda un led e invii il valore 0 (e funziona) mentre se è 10 (legge solo 0) accenda un altro led e invii il corrispettivo 10

Per la lettura, a quanto mi sembra viene letto carattere per carattere, quindi dovrei impostare dei caratteri di fine stringa ma, è possibile utilizzare una funzione (interrupts??) che legga sempre?
seconda cosa volevo capire se le stringhe ricevute + e - che mi determinano o meno la connessione ci devono essere sempre...

grazie mille
Andrea

la seriale già funziona utilizzando gli interrupt e mettendo i dati letti in un buffer. Il carattere di fine stringa standard è lo '\0' (è un solo carattere, lo \ davanti serve per indicare un carattere speciale)

seconda cosa volevo capire se le stringhe ricevute + e - che mi determinano o meno la connessione ci devono essere sempre...

no, però non esiste un modo per sapere se la comunicazione seriale è stata stabilita, a meno che non si ricevano dati. In pratica non puoi sapere se dll'altra parte qualcuno ti sta ascoltando (al contrario del TCP o altri protocolli)

il resto è logica di programmazione, l'unica è dare un'occhiata agli esempi base che ci sono salvati nell'ide (il programma in cui si scrive il codice)

ok.. quindi l'idea è quella di ciclare finchè non trovo '\0' giusto?
visto che non c'è un modo per capire se la comunicazione è stabilita o meno posso crearmi una sorta di protocollo.
una cosa, il buffer viene svuotato dopo ogni read o c'è possibilità di trovare spazzatura all'interno??
grazie mille!

lesto:
no, però non esiste un modo per sapere se la comunicazione seriale è stata stabilita, a meno che non si ricevano dati. In pratica non puoi sapere se dll'altra parte qualcuno ti sta ascoltando (al contrario del TCP o altri protocolli)

La seriale è un mezzo fisico, il TCP/IP è un protocollo, sono due cose molto differenti, il secondo si usa sul primo, per assurdo nulla vieta di utilizzare il TCP/IP con le comunicazioni seriali.
Per sapere se una comunicazione è andata a buon fine con la seriale basta implementare un protocollo minimale, p.e. un semplice timeout entro il quale chi riceve i dati deve rispondermi con un "ok", è sufficiente anche un singolo carattere, se questo non avviene vuol dire che c'è stato un problema.

si certo.. questo lo so, chiedevo solo qualche delucidazione in merito al codice.. se è giusto o meno...per esempio

myByte = SpiSerial.read();

read() legge un carattere alla volta?

ho fatto delle modifiche trovando degli esempi in rete... il problema è che ora non va nulla..

void loop () {
  //simple feedback from Arduino
  
  //read the serial port and create a string out of what you read
  //readSerialString(serInString, serInIndx);
  readSerialString();
  
  //do somenthing else perhaps wait for other data or read another Serial string
  //Serial.println ("------------ arduino is doing somenthing else ");
  if (serInString=="0")
           {
             if(led1)
             {
               digitalWrite(3,LOW);
               led1 = false;
             }
             else
             {
               digitalWrite(3,HIGH);
               led1 = true;
         
             }
             SpiSerial.print("0");
           }
           if (serInString == "10")
           {
              if(led2)
             {
               digitalWrite(7,LOW);
               led2 = false;
             }
             else
             {
               digitalWrite(7,HIGH);
               led2 = true;
         
             }
             SpiSerial.print("10");
           }
  //try to print out collected information. it will do it only if there actually is some info.
  printSerialString();
  
  //slows down the visualization in the terminal
}



void readSerialString () {
    int sb;   
    if(SpiSerial.available()) { 
       //Serial.print("reading Serial String: ");     //optional confirmation
       while (SpiSerial.available())
       { 
          sb = SpiSerial.read();             
          serInString[serInIndx] = sb;
          serInIndx++;
          //serialWrite(sb);                        //optional confirmation
       }
       //Serial.println();
    }  
}

//print the string all in one time
//this func as well uses global variables
void printSerialString() {
   if( serInIndx > 0) {
      Serial.print("Arduino memorized that you said: ");     
      //loop through all bytes in the array and print them out
      for(serOutIndx=0; serOutIndx < serInIndx; serOutIndx++) {
          Serial.print( serInString[serOutIndx] );    //print out the byte at the specified index
          //serInString[serOutIndx] = "";            //optional: flush out the content
      }        
      //reset all the functions to be able to fill the string back with content
      serOutIndx = 0;
      serInIndx  = 0;
      Serial.println();
   }

}

l'output dato da arduino è questo:

Arduino memorized that you said: C
Arduino memorized that you said: onnected
Arduino memorized that you said:  via Ad-
Arduino memorized that you said: Hoc on R
Arduino memorized that you said: obotKea

Arduino memorized that you said: 
Using S
Arduino memorized that you said: tatic IP
Arduino memorized that you said: 
IF=UP

Arduino memorized that you said: 
DHCP=OF
Arduino memorized that you said: F
IP=16
Arduino memorized that you said: 9.254.1.
Arduino memorized that you said: 1:80
NM
Arduino memorized that you said: =255.255
Arduino memorized that you said: .0.0
GW
Arduino memorized that you said: =0.0.0.0
Arduino memorized that you said: 
Listen
Arduino memorized that you said:  on 80 

Arduino memorized that you said: 

Arduino memorized that you said: +
Arduino memorized that you said: 0
Arduino memorized that you said: 0
Arduino memorized that you said: 1
Arduino memorized that you said: 0

raaden:
ok.. quindi l'idea è quella di ciclare finchè non trovo '\0' giusto?
visto che non c'è un modo per capire se la comunicazione è stabilita o meno posso crearmi una sorta di protocollo.
una cosa, il buffer viene svuotato dopo ogni read o c'è possibilità di trovare spazzatura all'interno??
grazie mille!

esatto, cosa che però nel tuo ultimo codice NON fai. Ogni loop prendi il buffer della seriale (tutto e non solo un carattere) e lo stampi, ma nulla ti avvisa del fine stringa. NON credo che lo '\0' venga stampato via seriale, però lo '\n' sì (a capo) se vuoi leggere riga per riga, oppure lo spazio ' ' se vuoi leggere parola per parola.

Il buffer NON si azzere ogni read, ma viene solo eliminato il carattere letto. Per azzerere il buffer senza leggerlo c'è la funzione Serial.flush().

Ti consiglio nella funzione di lettura della seriale, di leggere tutto il buffer -a meno che- tu non trovi uno spazio o '\n', a seconda se vuoi leggere parole o righe. Servirà a nche una variabile "flag"ad avvisare che la stringa è completa oppure ancora parziale e serve un altro ciclo di lettura prim di stamparla

Ah quando hai letto uns stringa, ricordati SEMPRE di mettere lo '\0' finale, altrimenti funzioni che usano le stringhe (vedi strlen, Serial.print, etc..) impazziscono.

astrobeed:

lesto:
no, però non esiste un modo per sapere se la comunicazione seriale è stata stabilita, a meno che non si ricevano dati. In pratica non puoi sapere se dll'altra parte qualcuno ti sta ascoltando (al contrario del TCP o altri protocolli)

La seriale è un mezzo fisico, il TCP/IP è un protocollo, sono due cose molto differenti, il secondo si usa sul primo, per assurdo nulla vieta di utilizzare il TCP/IP con le comunicazioni seriali.
Per sapere se una comunicazione è andata a buon fine con la seriale basta implementare un protocollo minimale, p.e. un semplice timeout entro il quale chi riceve i dati deve rispondermi con un "ok", è sufficiente anche un singolo carattere, se questo non avviene vuol dire che c'è stato un problema.

se la seriale è il mezzo, come si chiama il protocollo che dice che sto usando 10 bit, nessuno di parità e uno di stop? io davo per scontato che si chiamasse sempre seriale :grin: (azz ho dato uno sguardo, il protocollo è rs-232, giusto?)

si, avevo intuito il problema.. ora ho risolto quella parte... secondo voi è corretta una cosa del genere??

#include "WiFly.h"
//#include <WString.h>
#include "string.h"
#include "Servo.h"
//#include "Credentials.h"
Servo myservo5;
Servo myservo6;
int pos5=90;
int pos6=90;
int pin2=0;


void setup() 
{

 Serial.begin(9600);
 SpiSerial.begin();

 myservo5.attach(5);
 myservo6.attach(6);
 pinMode(7, OUTPUT);
 pinMode(8, OUTPUT);
 pinMode(3, OUTPUT);
 pinMode(2, INPUT);
 digitalWrite(7,LOW);
 digitalWrite(8,LOW);
 digitalWrite(3,LOW);

}

String myString= String(100);
boolean dataReceiving = false;
String readString = String(100);
boolean led1 = false;
boolean led2 = false;
int serInIndx = 0;
void loop () {
  //simple feedback from Arduino
  
  //read the serial port and create a string out of what you read
  //readSerialString(serInString, serInIndx);
  if(readSerialString())
  {
    if (myString.equals("0"))
           {
             if(led1)
             {
               digitalWrite(3,LOW);
               led1 = false;
             }
             else
             {
               digitalWrite(3,HIGH);
               led1 = true;
         
             }
             SpiSerial.print("0");
           }
           if (myString.equals("10"))
           {
              if(led2)
             {
               digitalWrite(7,LOW);
               led2 = false;
             }
             else
             {
               digitalWrite(7,HIGH);
               led2 = true;
         
             }
             SpiSerial.print("10");
           }
  }
  pin2 = digitalRead(2);
  if(pin2 != 0)
  {
    Serial.print("input: ");
    Serial.print(pin2);
  }
  printSerialString();
  
  //slows down the visualization in the terminal
}



boolean readSerialString () 
{
    boolean dataRead = false;
    if(SpiSerial.available()) 
    { 
      myString = "";
      serInIndx = 0;
       while (SpiSerial.available())
       { 
          char c = SpiSerial.read();
          //read char by char HTTP request
          Serial.print(c);
          if(c=='+') //se trovo + inizia la comuinicazione abilito datareceiving
          {
               dataReceiving = true;
               Serial.print("start comunication\n");
               readString = "";
          }
          else if ((readString.length() < 100) && (dataReceiving))
          {
             //store characters to string
             if(c=='-') //se a comunicazione attiva ricevo - significa che la comunicazione non è attiva
             {
               dataReceiving = false;
               Serial.print("end comunication\n");
             }
             else
             { 
                 serInIndx++;
                 
                 if(c == '

inoltre volevo chiedervi per gli input come posso ragionare?? sul pin 2 ho messo un bottone c'è un modo per leggere il cambio stato?
ho provato così

pin2 = digitalRead(2);
  if(pin2 != 0)
  {
    Serial.print("input: ");
    Serial.print(pin2);
  }

ma il risultato è pessimo... sembra che lo stato 1 sia quello non attivo, mentre lo 0 quello attivo (premo il bottone)
mi è un po' difficile entrare nell'ottica di questo linguaggio arrivando da obj-c...
grazie a tutti ;))//carattere di fine corsa quando lo trovo la mia stringa è completa e quindi la posso processare
                {
                  //readString.concat(c);
                  myString = readString;
                  readString = "";
                  dataRead = true;
                   
                }
                else
                {
                  readString.concat(c);
                }
            }
          }
      }
    }
    return dataRead;
}

//print the string all in one time
//this func as well uses global variables
void printSerialString()
{
  if( serInIndx > 0) {
      Serial.print("Arduino said: ");   
      //loop through all bytes in the array and print them out
      Serial.print(myString);
      /*for(serOutIndx=0; serOutIndx < serInIndx; serOutIndx++) {
          Serial.print( serInString[serOutIndx] );
         
          //print out the byte at the specified index
          //serInString[serOutIndx] = "";            //optional: flush out the content
      }  */     
      //reset all the functions to be able to fill the string back with content
      Serial.println();
  }
}


inoltre volevo chiedervi per gli input come posso ragionare?? sul pin 2 ho messo un bottone c'è un modo per leggere il cambio stato?
ho provato così

§DISCOURSE_HOISTED_CODE_1§


ma il risultato è pessimo... sembra che lo stato 1 sia quello non attivo, mentre lo 0 quello attivo (premo il bottone)
mi è un po' difficile entrare nell'ottica di questo linguaggio arrivando da obj-c...
grazie a tutti ;)

arduino lo puoi programmare col c++, però mancano alcune funzioni.

per il pulsante guarda l'esempio di debounce, in pratica quando premi il pulsante l'input oscilla

il codice non è correttissimo per la ricezione della stringa. Cosa succede se ricevi mezza stringa e l'altra mezza nel loop successivo? che entrambi i pezzi vengono scartati.

grazie per il consiglio! uso lo stesso sistema di debounce, ci avevo anche pensato in effetti :wink:
cosa consigli per la lettura della stringa? in effetti hai ragione..

potrei inserire un carattere di inizio stringa, così azzero la stringa letta solo quando ricevo il carattere di inizio....

esatto, e il contenitore della stringa parziale diviene gloabale, altrimenti viene resettato comunque a fine funzione.

ps. complimenti, stai imparando in fretta :smiley:

perfetto... il problema sarà ora iniziare a creare il wrapper da distribuire poi...:slight_smile:

grazie.. diciamo che nell'ultimo anno ho lavorato solo per iOS e con java però mi ricordo ancora la fatica fatta nel creare moduli per il kernel in uni...:wink: