ultimo aggiornamento 23 novembre 2014


 

Prima di passare alla descrizione dei programmi da installare che sono due uno per il Robot e uno per la stazione di controllo, è opportuno soffermarsi su alcuni problemi incontrati durante la realizzazione del programma per la stazione di controllo. Questi non si erano evidenziati nelle prime fasi poiché era previsto solamente un flusso di dati semplice, come l’invio di un solo carattere e con una direzione che era dalla Scheda Arduino Esplora verso la scheda Arduino Nano. I problemi si sono verificati quando si è tentato di inviare dei dati, come la telemetria dei sensori, dal robot verso la scheda esplora.

 

homotix

PCBA

OurPCB

Primo problema – Velocità di trasmissione

I moduli bluetooth utilizzati permettono una velocità massima di 115200 bps, che è tra l’altro il valore impostato di default.
Ora, se questo valore può andare bene per collegamenti semplici con la UART implementata in hardware sul chip. presente sulla scheda, i problemi si presentano quando si utilizza una seriale UART creata per via software, per cui un primo passo per evitare questo problema è stato ridurre a 9600 bps la velocità.

Secondo problema - Particolarità del processore della scheda Arduino Esplora

Il processore della scheda Arduino Esplora è un ATMEGA32U4 che è lo stesso della scheda Leonardo, una delle sue particolarità è che ha già a bordo un’interfaccia USB.
Questo ha due implicazioni importanti: il costo più contenuto e che è in grado di operare in qualsiasi modalità USB. Ciò significa che si possono creare delle Human Interface Device ( HID ) , come mouse e tastiere e stampanti. Per il collegamento del modulo Bluetooth con il processore, si sono utilizzati i due pin digitali disponibili connessi alle porte D3 e D11.

Per la creazione della porta virtuale si sono utilizzati il pin 11 come RX e il pin 3 come TX.

SoftwareSerial mySerial(11, 3); // Definizione RX, TX per collegamento

Questa è la sola configurazione possibile in quanto, come riportato nella pagina del sito Arduino che descrive i vari comandi della libreria Software Serial, sono riportate le seguenti limitazioni note

Non tutti i pin della Leonardo supportano il cambio di interrupts, solo i seguenti possono essere usati come RX: 8, 9, 10, 11, 14 (MISO), 15 (SCK), 16 (MOSI).

Conversione dei valori ricevuti dal robot.

Altro problema è stato quello di come inviare e come decodificare poi i dati ricevuti dal robot.
La soluzione utilizzata, ha previsto sul robot la creazione di una funzione che, dopo aver letto i vari sensori e convertiti a seconda del tipo, li invia alla seriale tramite dei comandi
Serial.println() ; se il valore da inviare è decimale, questo viene prima moltiplicato per 10, in modo da inviare sempre un numero intero.

/*Trasmissione telemetria*/
void telemetria()
{
  led_on ();
  //Preparazione dei valori
  float vbatt = (analogRead(vbat)*((readVcc()/1000.0)/1024));
  int batteria = vbatt*10;

  int fotocellula = analogRead(foto);  // lettura grezza dall'adc

  int reading = analogRead(temp);
  float voltage = (reading * 5.0) / 1024;
  int tempC=((voltage - 0.5) * 100)*(-1);
  int temperatura = tempC *10;

  distance = Dist.getDistanceCentimeter();

  //Invio valori verso stazione di comando
  Serial.println (batteria);
  Serial.println (fotocellula);    
  Serial.println (temperatura);
  Serial.println (distance);
  Serial.print ("F");
  led_off ();   
}

Sulla Stazione di controllo, il comando utilizzato per decodificare i valori ricevuti, utilizza la funzione mySerial.parseInt() che restituisce il primo numero intero dal buffer seriale. Caratteri che non sono numeri interi (o il segno meno) sono saltati. mySerial.parseInt() termina con il primo carattere che non è una cifra.
Per ricreare i valori decimali si è nuovamente diviso il valore per 10, successivamente si è utilizzato il comando
 sprintf() che permette di creare una stringa con la giusta formattazione e con i valori calcolati, per esempio :

 sprintf(tensione1,"%d.%d V",iBattVoltage,dBattVoltage);

Tensione1 è il nome della stringa in uscita.
"%d.%d V" è il formato della stringa formato dalla prima cifra (nel nostro caso il valore assunto da iBattVoltage), dal “punto”, dalla seconda cifra (nel nostro caso il valore assunto da dBattVoltage)

Programma Stazione di controllo

Il programma per la stazione di controllo denominato Robot_Littlebot_controller.ino, può essere riassunto nelle seguenti funzioni:

Il joystick ha la funzione di muovere il robot nelle quattro direzioni, mentre i tasti assumono la seguente funzione:
1 - emissione suono
3 - accensione/spegnimento faro frontale
2-4 rotazione servo frontale

Il collegamento bluetooth della scheda Arduino Esplora è effettuato impostando il modulo come Master (vedere anche la pagina Scheda Arduino Esplora e collegamento modulo Bluetooth)
Per fare questo, occorre inviare al modulo alcuni comandi che sono presenti nella sezione setup del programma.
Dopo aver impostato la velocità di trasmissione della seriale a 115200 bps (che è quella di default del modulo), viene inviato il comando per entrare in command mode rappresentato da print (“$$$”) a cui deve seguire una breve pausa.

mySerial.begin(115200);
  mySerial.print("$");
  mySerial.print("$");
  mySerial.print("$");
  delay(100);

Quindi, s’invia il comando println(“SM,1”) che imposta il modulo come Master.
A questo punto indichiamo a quale modulo deve connettersi mediante il comando println("C, <address>) dove <address> deve essere sostituito dal codice MAC del vostro modulo slave, questo numero si trova scritto sull’esterno del modulo, ed è formato da 12 cifre.

 mySerial.println("SM,1"); 
  delay(100);
  //inserire il codice MAC del modulo Slave
  mySerial.println("C,000666644021");
  delay(100);


Dopo una nuova pausa impostiamo il valore della velocità di trasmissione a 9600 con il comando

mySerial.println("U,9600,N");

che cambia temporaneamente il baudrate a 9600, no parity, questo alla prossima riaccensione del modulo si riporterà al valore di 115200.
Si trasmetterà quindi il comando println("---") che permette l’uscita dal Command Mode, dopo un’ulteriore pausa con il comando
mySerial.begin(9600);
Si inizializza nuovamente la seriale di collegamento con il bluetooth a 9600.

Sotto le righe di codice corrispondenti:

 mySerial.begin(115200);
  mySerial.print("$");
  mySerial.print("$");
  mySerial.print("$");
  delay(100);
  mySerial.println("SM,1"); 
  delay(100);
  //inserire il codice MAC del proprio modulo Slave
  mySerial.println("C,000666644021");
  delay(100);
  mySerial.println("U,9600,N");  // Cambia temporaneamente il baudrate a 9600, no parity
  mySerial.println("---"); //Uscita command mode
  delay (100);
  mySerial.begin(9600);  // Reinizializza la seriale bluetooth 9600
  delay (100);

Per il resto, il programma dovrebbe essere sufficientemente commentato da comprenderne le funzioni.

Nota sul funzionamento.

Una nota per chi utilizzerà il programma: nonostante tutte le prove e i vari tentativi di correzione, per un perfetto funzionamento del programma, occorre compiere due reset consecutivi della scheda Arduino Esplora, tramite il tasto presente sulla scheda stessa, affinché il programma funzioni correttamente.

Programma robot

Il programma per il robot denominato Robot_Littlebot_robot.ino è una versione più completa di quello già utilizzato per testare la scheda.
Per il comando del robot sono disponibili i seguenti comandi:i

I comandi disponibili sono accessibili inviando i seguenti comandi:
b - Legge tensione della batteria
t - Legge temperatura
d - Legge distanza
l - Legge luminosità
s - Emette un “BIP"
k - Accende il faro (se acceso lo spegne)
n - Accende led
m - Spegne led
p -> Servo a DX
i -> Servo a SX
o -> Servo al centro;
8 -> Robot avanti;
2 -> Robot indietro;
4 -> Robot a SX;
6 -> Robot a DX;
0 -> Robot fermo;
q -> Trasmette telemetria;

Se s’invia il comando "h", si avrà l’elenco delle opzioni.

Alcune particolarità del programma

Il programma utilizza una libreria denominata DistanceGP2Y0A21YK.h scritta da Jeroen Doggen che può essere scaricata al seguente link
E’ possibile modificare la velocità del robot modificando il valore della variabile vel che, attualmente, è impostata al valore di 100.

#define vel 100      //velocità dei motori

il valore può variare teoricamente tra 0 e 255 ma se è troppo basso, i motori non ruoteranno.

Questo perché i motori sono controllati in PWM (Pulse Width Modulation). Con questo sistema, la velocità del motore non viene regolata variando la tensione, ma variando il tempo durante il quale, l'intera tensione di alimentazione viene applicata ai terminali del motore.
Per l’impostazione del modulo bluetooth che in questo caso sarà impostato come SLAVE, si segue una procedura simile a quella vista per la stazione di controllo, l’unica variazione è che il comando in questo caso sarà:

Serial.println("SM,0");

che imposta appunto il modulo come Slave.
Ecco in dettaglio la parte di programma:

  Serial.begin(115200); //imposta la porta di comunicazione con il modulo
  Serial.print("$");
  Serial.print("$");
  Serial.print("$");
  delay(100);
  Serial.println("SM,0"); // Imposta il modulo come slave
  delay(100);
  Serial.println("U,9600,N") // Cambia temporaneamente il baudrate
                             // a 9600, no parity
  delay(100);
  Serial.println("---"); //Uscita command mode
  delay(100);
  Serial.begin(9600);  // Reinizializza la seriale bluetooth 9600

Nota:

II modulo Bluetooth comunica con Arduino Nano attraverso la porta hardware UART, la stessa porta è anche utilizzata dall'IDE Arduino per effettuare il download del firmware.
Esiste quindi, un accesso contemporaneo alla risorsa e chiaramente le due cose non possono funzionare insieme.
Quando si deve programmare la scheda Arduino NANO, occorre rimuovere il modulo Bluetooth, effettuare il download, inserire nuovamente il modulo Bluetooth ed infine accendere la scheda.

Listato programma stazione di controllo 

// caricamento librerie 
#include <SoftwareSerial.h>
#include <SPI.h>
#include <Esplora.h>
#include <TFT.h>

//Definizione variabile di servizio
int iBattVoltage = 0;
int dBattVoltage = 0;
char tensione1 [10];
int itemperatura = 0;
int dtemperatura = 0;
char temperatura1 [10];
char fotocellula1[10];
char distanza1[10];
boolean buttonStates[8];

SoftwareSerial mySerial(11, 3); // Definizione RX, TX per collegamento
// Modulo bluetooth 
/* 
 Questa matrice contiene i nomi dei pulsanti che sono letti. 
 Più tardi, nello sketch, questi nomi saranno usati con 
 il metodo Esplora.readButton (x), dove x è uno di questi pulsanti. 
 */

const byte buttons[] = {
  JOYSTICK_DOWN, // Indietro
  JOYSTICK_LEFT, // Sinistra
  JOYSTICK_UP,   // Avanti
  JOYSTICK_RIGHT,// Destra 
  SWITCH_RIGHT,  // Servo destra
  SWITCH_LEFT,   // Servo sinistra
  SWITCH_UP,     // Accende faro
  SWITCH_DOWN,   // Suono
};
/* 
 Questo array dice qaule carattere inviare a seconda 
 del tasto premuto.
 */
const char keystrokes[] = {
  '2', // Indietro
  '4', // Sinistra
  '8', // Avanti
  '6', // Destra
  'i', // Servo DX
  'p', // Servo Sx
  'k', // Gestione faro
  'q'  // Bip
};

// Impostazione del programma
void setup() {
  Serial.begin(115200);
  //Imposta il modulo BlueSMiRF SILVER come MASTER
  //e setta il numera MAC del ricevente slave
  mySerial.begin(115200);
  mySerial.print("$");
  mySerial.print("$");
  mySerial.print("$");
  delay(100);
  mySerial.println("SM,1");  
  delay(100);
  //inserire il codice MAC del modulo Slave
  mySerial.println("C,000666644021");
  delay(100);
  mySerial.println("U,9600,N");  // Cambia temporaneamente il baudrate a 9600, no parity
  mySerial.println("---"); //Uscita command mode
  delay (100);
  mySerial.begin(9600);  // Reinizializza la seriale bluetooth 9600
  delay (100);
  //------------------- 
  Esplora.tone(500, 150);
  mySerial.setTimeout(200);
  EsploraTFT.begin();
  EsploraTFT.background(0,0,0); //sfondo nero
  EsploraTFT.setTextSize(2);
  EsploraTFT.stroke(0,255,0); //colore del testo verde
  EsploraTFT.text("Comando Robot",0,0);
  EsploraTFT.stroke(255,0,0); //colore del testo rosso
  EsploraTFT.text("LittleBot",25,25);
  EsploraTFT.setTextSize(1);
  EsploraTFT.stroke(255,255,255); //colore del testo bianco
  EsploraTFT.text("By adrirobot - ver. 1.0",10,45);
  EsploraTFT.stroke(0,255,255); //colore del testo cyano
  EsploraTFT.text("JOYSTICK  -Direzione",0,80);
  EsploraTFT.text("SWITCH 1  -Accensione faro",0,90);
  EsploraTFT.text("SWITCH 2-4-SX-DX Servo",0,100);
  EsploraTFT.text("SWITCH 3  -Emissione suono",0,110);
  Esplora.tone(500, 150);
  delay (2000); //pausa per mostrare i comandi
  EsploraTFT.stroke(0,0,0);
  EsploraTFT.fill(0,0,0);
  EsploraTFT.rect(0,80, 200, 7); //Cancellazione valore
  EsploraTFT.rect(0,90, 200, 7);
  EsploraTFT.rect(0,100, 200, 7);
  EsploraTFT.rect(0,110, 200, 7);
  EsploraTFT.setTextSize(2);
  EsploraTFT.stroke(0,255,255); //colore del testo ciano
  EsploraTFT.text("Telemetria",20,60);   
  EsploraTFT.setTextSize(1);
  EsploraTFT.stroke(0,255,0); //colore del testo verde
  EsploraTFT.text("Batteria    :",0,90);
  EsploraTFT.text("Luminosita' :",0,100);
  EsploraTFT.text("Temperatura :",0,110);
  EsploraTFT.text("Distanza    :",0,120);
  Esplora.tone(800, 300);
}
/*
 Dopo che il setup () è finito, questo codice viene eseguito in modo continuo. 
 Qui controlliamo costantemente lo stato dei pulsanti e del Joystick.
 */
void loop() // LOOP di lettura tasti e invio carattere
{ 
  // Lettura pulsanti:
  for (byte thisButton=0; thisButton<8; thisButton++) 
  {
    boolean lastState = buttonStates[thisButton];
    boolean newState = Esplora.readButton(buttons[thisButton]);
    if (lastState != newState) { // Il tasto è cambiato!
      /* 
       La biblioteca Keyboard consente di di riconoscere "pressione" e "rilascio"
       dei tasti come due azioni distinte. Queste azioni possono essere 
       legati ai pulsanti che stiamo azionando.
       */
      if (newState == PRESSED) {
        mySerial.print(keystrokes[thisButton]);
      }
      else if (newState == RELEASED) {
        mySerial.print("0");
      }
    }
    // Memorizza il nuovo stato del pulsante, in modo da poter percepire successivamente la differenza
    buttonStates[thisButton] = newState;
    telemetria (); //stampa telemetria su display 
  }
  delay(50); //Leggera attesa tra un controllo e l'altro. 
}

void telemetria ()        
{
  while (mySerial.available()>1) {
    //Lettura valori
    int BatteryValue = mySerial.parseInt();
    int luce = mySerial.parseInt(); 
    int temperatura = mySerial.parseInt(); 
    int distanza = mySerial.parseInt(); 
    int www = mySerial.parseInt();//valore non utilizzato
    //Preparazione valori per stampa su display
    //Tensione batteria Robot
    float fBattVoltage = ((BatteryValue/10.0)-5);
    iBattVoltage = (int)fBattVoltage; // Unita' valore della tensione
    dBattVoltage = (fBattVoltage-iBattVoltage)*10; // Decimali valore della tensione
    sprintf(tensione1,"%d.%d V",iBattVoltage,dBattVoltage);
    Serial.print("Tensione batteria: ");
    Serial.println(tensione1);
    //Valore luminosita'
    sprintf(fotocellula1,"%d",luce);
    Serial.print("Valore Luce: ");
    Serial.println(fotocellula1);
    //Valore temperatura
    float ftemperatura = (temperatura/10.0);
    itemperatura = (int)ftemperatura; // Unita' valore della tensione
    dtemperatura = (ftemperatura-itemperatura)*10; // Decimali valore della tensione
    sprintf(temperatura1,"%d.%d C",itemperatura,dtemperatura);
    Serial.print("Temperatura: ");
    Serial.println(temperatura1);
    //Valore distanza
    //  char distanzaStr[5]; //Asseganzione a char
    sprintf(distanza1,"%d cm",distanza);
    Serial.print("Distanza: ");
    Serial.println(distanza1);
    //Stampa valori su display
    EsploraTFT.stroke(0,0,0);//colore nero
    EsploraTFT.fill(0,0,0);
    EsploraTFT.rect(100,90, 40, 7); //Cancellazione valore
    EsploraTFT.rect(100,100, 40, 7);
    EsploraTFT.rect(100,110, 40, 7);
    EsploraTFT.rect(100,120, 40, 7);
    EsploraTFT.stroke(255,255,0); //colore del testo giallo
    EsploraTFT.text(tensione1, 100, 90); 
    EsploraTFT.text(fotocellula1, 100, 100);  
    EsploraTFT.text(temperatura1,100,110);
    EsploraTFT.text(distanza1,100,120);
    Esplora.tone(800, 150); // Dati completati
  }
}

Listato programma robot 

#include <DistanceGP2Y0A21YK.h> //Gestione sensore infrarosso

/* Pin Digitali */
#define buzzer 2
#define PWMA 3
#define AIN1 5
#define AIN2 4
#define PWMB 9
#define BIN1 7
#define BIN2 8
#define STBY 6
#define servo_pin 11
#define luce 12
#define ledpin 13

/*Pin analogici*/
#define vbat 1
#define foto 0
#define temp 2
#define sharp 7

/*Definizione variabili*/
#define vel 100      //velocità dei motori
int servo1 = 1250;   //test servo tilt position (0 to 180)
int minPulse1= 600;   // posizione minima 0°
int maxPulse1= 2400; // posizione massima 180°
int turnRate1= 100;  // ruota di 10° alla volta
int pulseWidth1;     // servo pulse width
int centerServo1;
DistanceGP2Y0A21YK Dist;
int distance;
int  val = 0; //faro

void setup() {
  //Impostazione del modulo bluetooth
  Serial.begin(115200); //imposta la porta di comunicazione con il modulo
  Serial.print("$");
  Serial.print("$");
  Serial.print("$");
  delay(100);
  Serial.println("SM,0"); // Imposta il modulo come slave
  delay(100);
  Serial.println("U,9600,N") // Cambia temporaneamente il baudrate
                             // a 9600, no parity
  delay(100);
  Serial.println("---"); //Uscita command mode
  delay(100);
  Serial.begin(9600);  // Reinizializza la seriale bluetooth 9600
  delay (200);
  //Impostazione pin 
  pinMode(PWMA,OUTPUT);
  pinMode(AIN1,OUTPUT);
  pinMode(AIN2,OUTPUT);
  pinMode(PWMB,OUTPUT);
  pinMode(BIN1,OUTPUT);
  pinMode(BIN2,OUTPUT);
  pinMode(STBY,OUTPUT);
  pinMode(luce, OUTPUT);
  pinMode(ledpin, OUTPUT);
  pinMode(servo_pin, OUTPUT);
  robot_accendi();
  servo_center();
  Dist.begin(sharp);
}
void loop() {
  while (Serial.available() < 1) {
  }                         // Attesa sino a quando riceve un carattere
  char val = Serial.read(); // Legge il carattere dal modulo Bluetooth e lo salva nella variabile val
  switch(val)               // Esegue i comandi in base al carattere ricevuto
  {
  case 'p':// Se il carattere ricevuto è 'i' esegue la routine servo a DX
    servo_dx();
    break;
  case 'i':// Se il carattere ricevuto è 'i' esegue la routine servo a DX
    servo_sx();
    break; 
  case 'o':// Se il carattere ricevuto è 'l' esegue la routine servo al centro
    servo_center();
    break; 
  case '8':// Se il carattere ricevuto è '8' esegue la routine Robot avanti
    robot_avanti ();
    break;
  case '2'://Se il carattere ricevuto è '2' esegue la routine Robot indietro
    robot_indietro ();
    break;
  case '4'://Se il carattere ricevuto è '4' esegue la routine Robot sinistra
    robot_sinistra ();
    break;
  case '6'://Se il carattere ricevuto è '6' esegue la routine Robot destra
    robot_destra ();
    break;
  case 'k'://Se il carattere ricevuto è 'k' Accende/spegene faro frontale
    faro ();
    telemetria ();
    break;
  case 'l'://Se il carattere ricevuto è 'l' Legge la fotocellula
    leggi_luce ();
    break;  
  case 's'://Se il carattere ricevuto è 's' Emette un suono
    tone (buzzer,500,500); 
    break;
  case 'q'://Se il carattere ricevuto è 'q' Trasmette i dati dei sensori
    tone (buzzer,500,500);
    telemetria();
    break;
  case 't'://Se il carattere ricevuto è 't' Legge temperatura tramite LM35
    temperatura ();
    break;
  case 'b'://Se il carattere ricevuto è 'b' Legge tensione della batteria
    batteria ();
    break; 
  case 'd'://Se il carattere ricevuto è 'd' Legge la distanza di un'oggetto dal sensore
    distanza ();
    break;
  case 'n'://Se il carattere ricevuto è 'n' accende il led di segnalazione
    led_on ();
    break;
  case 'm'://Se il carattere ricevuto è 'm' spegne il led di segnalazione
    led_off ();
    break;  
  case '0'://Se il carattere ricevuto è '0' esegue la routine Robot fermo
    stop();
    break;
  case 'h'://Se il carattere ricevuto è 'h' esegue la routine HELP
    help();
    break;
  default:
    stop(); // Ferma il robot
    break;
  }
}
void stop (void)
{
  digitalWrite (AIN1,HIGH);
  digitalWrite (AIN2,HIGH);
  analogWrite(PWMA,vel);
  digitalWrite (BIN1,HIGH);
  digitalWrite (BIN2,HIGH);
  analogWrite(PWMB,vel);
}
void robot_indietro ()
{
  digitalWrite (AIN1,HIGH);
  digitalWrite (AIN2,LOW);
  analogWrite(PWMA,vel);
  digitalWrite (BIN1,HIGH);
  digitalWrite (BIN2,LOW);
  analogWrite(PWMB,vel);
  delay (200);
}
void robot_avanti ()
{
  digitalWrite (AIN1,LOW);
  digitalWrite (AIN2,HIGH);
  analogWrite(PWMA,vel);
  digitalWrite (BIN1,LOW);
  digitalWrite (BIN2,HIGH);
  analogWrite(PWMB,vel); 
  delay (200);
}
void robot_destra ()
{
  digitalWrite (AIN1,HIGH);
  digitalWrite (AIN2,LOW);
  analogWrite(PWMA,vel);
  digitalWrite (BIN1,LOW);
  digitalWrite (BIN2,HIGH);
  analogWrite(PWMB,vel);
  delay (200);  
}
void robot_sinistra ()
{
  digitalWrite (AIN1,LOW);
  digitalWrite (AIN2,HIGH);
  analogWrite(PWMA,vel);
  digitalWrite (BIN1,HIGH);
  digitalWrite (BIN2,LOW);
  analogWrite(PWMB,vel);
  delay (200);  
}
void robot_accendi ()
{
  digitalWrite(STBY,HIGH);
}
void robot_spegni()
{
  digitalWrite(STBY,LOW);
}
/* Muove il servo a destra*/
void servo_dx()
{
  pulseWidth1 = pulseWidth1 - turnRate1;
  if (pulseWidth1 < minPulse1) { 
    pulseWidth1 = minPulse1; 
  } 
  digitalWrite(servo_pin, HIGH);
  delayMicroseconds(pulseWidth1);
  digitalWrite(servo_pin, LOW);
  delay(20);
}
/* Muove il servo a Sinistra*/
void servo_sx()
{
  pulseWidth1 = pulseWidth1 + turnRate1;
  if (pulseWidth1 > maxPulse1) { 
    pulseWidth1 = maxPulse1; 
  }
  digitalWrite(servo_pin, HIGH);
  delayMicroseconds(pulseWidth1);
  digitalWrite(servo_pin, LOW);
  delay(20);
}
/* Posiziona il servo in centro*/
void servo_center()
{
  centerServo1 = maxPulse1 - ((maxPulse1 - minPulse1)/2);
  pulseWidth1 =  centerServo1;
  digitalWrite(servo_pin, HIGH);
  delayMicroseconds(pulseWidth1);
  digitalWrite(servo_pin, LOW);
  delay(20);
}
/* Accensione led segnalazione*/
void faro()
{
  if (digitalRead(luce) == HIGH) // il led era acceso?
  {
    digitalWrite(luce,LOW); // lo spengo
    Serial.println("Led spento");
  }
  else // il led era spento
  {
    digitalWrite(luce,HIGH); // lo accendo
    Serial.println("Led acceso");
  }
}
/* Accensione led segnalazione*/
void led_on()
{
  digitalWrite(ledpin, HIGH); // sets the LED on
}
/* Spegnimento led segnalazione*/
void led_off()
{
  digitalWrite(ledpin, LOW); // sets the LED off
}
/* Lettura della tensione della batteria*/
void batteria ()
{
  float vbatt = (analogRead(vbat)*((readVcc()/1000.0)/1024));
  Serial.print("Tensione batteria: "); 
  Serial.print (vbatt,1);
  Serial.println (" V");
}
/* Legge la temperatura */
void temperatura ()
{  
  /* Lettura sensore */
  int reading = analogRead(temp); 
  float voltage = (reading * 5.0) / 1024; 
  int tempC=((voltage - 0.5) * 100)*(-1);
  Serial.print("Temperatura: ");
  Serial.print(tempC,1);
  Serial.println(" gradi C");
}
/* Verifica funzionamento fotocellula */
void leggi_luce ()
{ 
  float lettura_foto = analogRead(foto);  // lettura grezza dall'adc
  Serial.print("Valore luce = ");
  Serial.println(lettura_foto,0);     //stampiamo il valore
}
/* Lettura distanza*/
void distanza()
{
  distance = Dist.getDistanceCentimeter();
  Serial.print("Distanza in centimetri: ");
  Serial.println(distance);
}
/*Trasmissione telemetria*/
void telemetria()
{
  led_on ();
  //Preparazione dei valori
  float vbatt = (analogRead(vbat)*((readVcc()/1000.0)/1024));
  int batteria = vbatt*10;

  int fotocellula = analogRead(foto);  // lettura grezza dall'adc

  int reading = analogRead(temp); 
  float voltage = (reading * 5.0) / 1024; 
  int tempC=((voltage - 0.5) * 100)*(-1);
  int temperatura = tempC *10;

  distance = Dist.getDistanceCentimeter();

  //Invio valori verso stazione di comando 
  Serial.println (batteria);
  Serial.println (fotocellula);     
  Serial.println (temperatura);
  Serial.println (distance);
  Serial.print ("F");
  led_off ();   
}
/* HELP*/
void help()
{
  Serial.print("\nComandi robot ");
  Serial.print("\nh -> Questo elenco");
  Serial.print("\nb -> Tensione della batteria");
  Serial.print("\nt -> Temperatura");
  Serial.print("\nd -> Legge distanza");
  Serial.print("\nl -> Legge luminosita'");
  Serial.print("\ns -> Emette un BIP");
  Serial.print("\nk -> Accende il faro");
  Serial.print("\nj -> Spegne il faro");
  Serial.print("\np -> Servo a DX");
  Serial.print("\ni -> Servo a SX");
  Serial.print("\no -> Servo al centro");
  Serial.print("\n8 -> Robot avanti");
  Serial.print("\n2 -> Robot indietro");
  Serial.print("\n4 -> Robot a SX");
  Serial.print("\n6 -> Robot a DX");
  Serial.print("\n0 -> Robot fermo");
  Serial.print("\nn -> Accende led");
  Serial.print("\nm -> Spegne led");
  Serial.print("\nq -> Trasmette telemetria");
}

/* Routine per rendere la letture ADC più accurata su Arduino tratta dal sito
http://provideyourown.com/2012/secret-arduino-voltmeter-measure-battery-voltage/
*/
long readVcc() {
  long result;
  // Read 1.1V reference against AVcc
  ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
  delay(2); // Wait for Vref to settle
  ADCSRA |= _BV(ADSC); // Convert
  while (bit_is_set(ADCSRA,ADSC));
  result = ADCL;
  result |= ADCH<<8;
  result = 1126400L / result; // Back-calculate AVcc in mV
  return result;
}

 

Elenco revisioni
23/11/2014 Emissione preliminare
Private Policy Cookie Policy Termini e Condizioni