domingo, 15 de junio de 2014

Projecte Final: ArduCotxe

Per Aurora Ripoll i Jose Ángel Mohedano


OBJECTIU: Crear un cotxet Ardudirigit. 

Que és capaç de fer l'ArduCotxe?



  • Avançar i retrocedir.
  • Girar a  la dreta i a l'esquerra. 
  • Parar-se. 
  • Indicar per la pantall LiquidCrystal quins són els moviments que està fent. 

Material necessari

  • Pel control Remot: 
- Arduino Micro Pro
- Protoboard
- Digi XBee(Coordinator AT)
- XBee Explorer 
- Resistències 10 KOhms (x5)
- Botons (x5)
- Cables connectors



  • Pel Cotxe:
- Arduino Uno
- Protoboard
- Digi XBee (Router AT)
- XBee Explorer
- Drivers L293D (x2)
- ServoMotor
- Motors DC de voltatge variable
- Estructura de plàstic
- Rodes i eixos de direcció
- Peces de Mecano
- Panralla LiquidCrystal
- Interruptor
- Porta piles de 6 V
- Cables connectors 
- Brides per subjectar




Funcionament Driver L293D

El driver utilitzat per fer aquest projecte ens permet controlar 2 motors de corrent contínua.



L'esquema bàsic del seu funcionament és el següent:






    • Pins alimentació L239D:
      • Vs (8) : Reb energia pel funcionament dels motors (4.5-36 V)
      • Vss(16): Alimentació del driver (4.5-7 V)
    • Pins d'habilitació: Pins d'intrucció al dirver. ENABLE1 pel motor 1 i ENABLE2 pel motor 2.
    • Pins de control: Ports de connexió a la placa Arduino i que permeten controlar els motors . INPUT1 i INPUT2 pel motor 1 i INPUT3 i INPUT4 pel motor 2. 
    • Pins alimentació motors: OUTPUT1 i OUTPUT2 pel motor 1 i OUTPUT3 i OUTPUT4 pel motor 2.
    • GROUND. Connexió a terra. 


Valors dels pins d'habilitació i control pel funcionament dels motors: 




ServoMotor

Motor amb eix de rendiment controlat. Es pot posicionar dins un rang d'actuació de 180º.

Aquest serà utilitzat per controlar l'eix de gir de les rodes.




1. Muntatge del circuit


  • Control remot:






  • Cotxe


2. Codi


  • Control remot:





int forward = 2;       // pin per anar recte     

int back = 7;          // pin per anar enrere

int right = 4;         // pin per anar a la dreta

int left = 5;          // pin per anar a l'esquerra 

int Stop = 6;          // pin per parar


void setup(){
    pinMode(forward, INPUT);
    pinMode(back, INPUT);
    pinMode(right, INPUT);
    pinMode(left, INPUT);
    pinMode(sos, INPUT);
    Serial1.begin(9600);

}

void loop(){   
  
    // Envia una F quant s'apreta el boto 'forward' (recte)
     
    if(digitalRead(forward) == HIGH && digitalRead(right)== LOW && digitalRead(left)== LOW && digitalRead(back)==LOW && digitalRead(Stop)==LOW)}
        Serial1.print('F');
        delay(30);
    }
    
    // Envia una R quant s'apreta el boto 'right' (dreta)
    
    if(digitalRead(forward) == LOW && digitalRead(right)== HIGH && digitalRead(left)== LOW && digitalRead(back)==LOW && digitalRead(Stop)==LOW){
        Serial1.print('R');            
        delay(30);
    }
    
    // Envia una L quant s'apreta el boto 'left' (esquerra)
    
    if(digitalRead(forward) == LOW && digitalRead(right)== LOW && digitalRead(left)== HIGH && digitalRead(back)==LOW) && digitalRead(Stop)==LOW){
        Serial1.print('L');            
        delay(30);
    }
    
    // Envia una B quant s'apreta el boto 'back' (enrere)
    
    if(digitalRead(forward) == LOW && digitalRead(right)== LOW && digitalRead(left)== LOW && digitalRead(back)==HIGH && digitalRead(Stop)==LOW){
        Serial1.print('B');            
        delay(30);
    }
    
    
   // Envia una S quant s'apreta el boto 'Stop' 
    
    if(digitalRead(forward) == HIGH && digitalRead(right)== LOW && digitalRead(left)== LOW&& digitalRead(back)==HIGH && digitalRead(Stop)==LOW){
        Serial1.print('S');            
        delay(30);
    }  
       


  • Cotxe:

#include <FastIO.h>
#include <I2CIO.h>
#include <LCD.h>
#include <LiquidCrystal.h>
#include <LiquidCrystal_I2C.h>
#include <LiquidCrystal_SR.h>
#include <LiquidCrystal_SR2W.h>
#include <LiquidCrystal_SR3W.h>
#include <Wire.h> 
#include <Servo.h> 

Servo myservo;

LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);

int missatge;
int input_6v_1=7; 
int input_6v_2=8 ; 
int enable6=6;


void setup(){

    pinMode(input_6v_1, OUTPUT);
    pinMode(input_6v_2, OUTPUT);
    pinMode(enable6, OUTPUT);
    lcd.begin(16,2);
    myservo.attach(9);
    lcd.setCursor(7,0); 

    Serial.begin(9600);
}

void loop(){
  
    if(Serial.available()>0){
     
      missatge = Serial.read();
      
        // Quan es rebi una F:
      
        if (missatge == 'F'){
          
          myservo.write(80);              // El servo es mante recte (en un angle aproximat de 80 graus)
          digitalWrite(enable6, HIGH);    // Activacio del pin d'habilitacio
          digitalWrite(input_6v_1, LOW);  
          digitalWrite(input_6v_2, HIGH); // El motor gira en sentit horari
          delay(30);
          Serial.print("FORWARD");
          lcd.clear();
          lcd.setCursor(3,0);
          lcd.print("FORWARD!");          // Mostra 'forward' per la pantalla LiquidCrystal

          }

        // Quant rebi una R: 

        else if (missatge == 'R'){
          
          myservo.write(105);              // El servo gira a la drata (angle aproximat de 105 graus)
          delay(30);
          Serial.print("RIGHT");
          lcd.clear();
          lcd.setCursor(5,0);
          lcd.print("RIGHT!");             // Mostra 'right' per la pantalla LiquidCrystal
          
         }

       // Quant rebi una L:
       
        else if (missatge == 'L'){
          myservo.write(55);               // El servo gira a l'esquerra (angle aproximat de 55 graus)
          delay(30);
          Serial.print("left");
          lcd.clear();
          lcd.setCursor(5,0);
          lcd.print("LEFT!");              // Mostra 'left' per pantalla
        }
        
        
        // Quant rebi una B:
        
        else if (missatge == 'B'){
          
          myservo.write(80);              // El servo es col·loca recte
          digitalWrite(enable6, HIGH);    // Activacio del pin d'habilitacio
          digitalWrite(input_6v_1, HIGH);
          digitalWrite(input_6v_2, LOW);  // El motor gira en sentit anti horari
          delay(30);
          Serial.print("BACK");
          lcd.clear();
          lcd.setCursor(5,0);
          lcd.print("BACK!");             // Mostra 'back' per la pantall LiquidCrystal
        }
        
        // Quant rebi una S:
        
        else if (missatge == 'S'){        
          myservo.write(80);              
          digitalWrite(enable6, LOW);    //ENABLE = 0. El motor no funciona. 
          delay(30);
          lcd.clear();
          lcd.setCursor(5,0);
          lcd.print("STOP");             // Mostra 'back' per la pantall
        }
     
}
   



3. Demostració



4. Problemes 


A més de complir amb les característiques actuals de l'Arducotxe volien incloure un nou estat funcional anomenat 'emergència'. Aquest seria activat prement un botó i el cotxet reaccionaria augmentant la seva velocitat, fent sonar una sirena, alternant el parpelleig de dos LED'S i mostrant per la pantalla LiquidCrystal la paraula 'URGÈNCIA!'.

Els principals impediments que ens hem trobat han estat els següents:

1) Augment de la velocitat: Control de dos drivers per diferents controls de velocitat.
2) Fer fer sonar la sirena i alternar el parpelleig dels LED's: Aquestes accions no les podem realitzar junt amb la resta de codi ja que no ens deixa interaccionar amb el cotxe mentre sona la sirena o parpelleig els LEDS.

Pensem que aquestes podrien ser unes possibles solucions: 

1) Utilitzar interrupcions amb les quals aconseguiríem que s'executessin tots dos codis "alhora", interrupcions de micro-segons que ens permetrien sentir la sirena alhora que actuem el comandament.

Després d'haver realitzat el muntatge i aconseguits els requisits bàsics proposats ens hem trobat en que el pes de l'estructura del cotxet, amb el circuit inclòs, fa que aquest no pugui aconseguir una velocitat idònia. Això és solucionaria aplicant una font d'alimentació amb major voltatge. 








sábado, 14 de junio de 2014

Lab 6.2: Collecting a Data in a computer

Per Aurora Ripoll i Jose Ángel Mohedano


OBJECTIU: Rebre dades utilitzant Python i les XBees en mode API. 

Per fer-ho s'haurà de configurar l'equip remot per recopilar periòdicament dades d'un o més dels deus pins i enviar-lo al coordinador. El coordinador haurà d'estar configurat en mode API2. En el programa Python creearem una funció que s'encarregarà de la recepció de cada paquet de dades. Em aquest lab ens limitarem a imprimir la informació rebuda per pantalla. 



Material: 

- Protoboard (x2)
- Digi XBee (x2)
- XBee Explorer
- LDR
- Resitencia de 20 kOhms
- Cables connectors
- Ordinador 





1. Circuit






2. Codi 

A executar des de el terminal: 


from xbee import ZigBee

print 'Printing data from remote XBee'

serial port = serial.Serial('COM3', 9600) // Dependrà del port on tinguem connectada la XBee Local
zigbee = ZigBee (serial_port, escaped=True)

while True:
try:
print zigbee.wait_read_frame()
expect KeyboardInterrupt:
break


serial_port.close()



3. Demostració




viernes, 6 de junio de 2014

Lab 6.1: Ping-ing a Sensor

OBJECTIU: Enviar dades des de un ordinador a la placa Arduino mitjançant un codi Python i dues XBees en mode API. 

Una XBee haurà d'estar connectada directament a l'ordinador i en mode Coordinator API. L'altra connectada a la placa Arduino en mode Router API. 

Com que ara interactuarem amb la XBee local utilitzant la llibreria Python, serà necessari que les dues XBees tinguin el mode API igual a 2 (Serial Interfacing, AP).

Mitjançant el codi Python la XBee local anirà enviant paquets en mode broadcast. En aquest cas  només hi ha una altra XBee connectada a la mateixa xarxa i per tant serà l'única receptora. Cada cop que la XBee remota rebi un paquet de la XBee local un LED parpadejarà 3 cops. 


Material necessari:


  • Placa Arduino UNO
  • Placa Protoboard
  • XBees Explorer (x2)
  • Digi XBee (x2)
  • Cables connectors
  • LED
  • Ordinador



1. Muntatge del circuit





2. Codi



Codi Python: 


#! /usr/bin/python

from xbee import ZigBee
import serial

import time
from datetime import datetime

ser = serial.Serial('COM4', 9600)
xbee = ZigBee(ser, escaped=True)

while True:
    try:
        tstart = datetime.now()
        xbee.send('tx',
                  frame_id='A',
                  dest_addr_long='\x00\x13\xa2\x00\x40\x8b\x44\xfa',
                  dest_addr='\xFF\xFE',
                  data='\x03')
        response = xbee.wait_read_frame();
        tend = datetime.now()
        print tend-tstart
        time.sleep(10);
    except KeyboardInterrupt:
        break

ser.close()


Codi Arduino:

#include <XBee.h> int ledPin = 13; XBee xbee = XBee(); XBeeResponse response = XBeeResponse(); // create reusable response objects for responses we expect to handle ZBRxResponse rx = ZBRxResponse(); void flashLed(int pin, int times, int wait) { for (int i = 0; i < times; i++) { digitalWrite(pin, HIGH); delay(wait); digitalWrite(pin, LOW); if (i + 1 < times) { delay(wait); } } } void setup() { Serial.begin(9600); xbee.begin(Serial); pinMode(ledPin, OUTPUT); flashLed(ledPin, 10, 50); // sets the LED off } void loop() { delay(1000); // 1. This will read any data that is available: xbee.readPacket(); if (xbee.getResponse().isAvailable()) { //flashLed(ledPin, 1, 1000); if (xbee.getResponse().getApiId() == ZB_RX_RESPONSE) { xbee.getResponse().getZBRxResponse(rx); //flashLed(ledPin, 1, 100); // sets the LED off flashLed(ledPin, rx.getData(0), 200); // sets the LED off } } }

3. Demostració




sábado, 31 de mayo de 2014

Lab 5.2: Sunset Sensor

Per Aurora Ripoll i Jose Ángel Mohedano


OBJECTIU: Crear un detector de posta de sol mitjançant la comunicació inal·làmbrica de dues XBees. 

Depenent de quina sigui la quantitat de llum rebuda per l'LDR s'interpretarà si és de dia, mitja tarda o nit. Amb això regularem la lluminositat d'un LED i a més a més es mostrarà per l'LCD en quin moment del dia estem. 


Material necessari:


  • Placa Arduino UNO
  • Placa Protoboard (x2)
  • XBees Explorer (x2)
  • Digi XBee (x2)
  • Cables connectors
  • Resistència 22 kOhms
  • LDR
  • LED's (x3)


1. Muntatge del circuit





2. Codi

#include <FastIO.h> #include <I2CIO.h> #include <LCD.h> #include <LiquidCrystal.h> #include <LiquidCrystal_I2C.h> #include <LiquidCrystal_SR.h> #include <LiquidCrystal_SR2W.h> #include <LiquidCrystal_SR3W.h> #include <Wire.h> LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); int LED_NIGHT=12; int LED_SUNSET=11; int LED_DAY=10; int debugLED=13; int analogValue=0; void setup(){ pinMode(LED_DAY, OUTPUT); pinMode(LED_SUNSET, OUTPUT); pinMode(LED_NIGHT, OUTPUT); pinMode(debugLED, OUTPUT); Serial.begin(9600); //LCD lcd.begin(16,2); } void loop(){ digitalWrite(LED_NIGHT,LOW); digitalWrite(LED_SUNSET,LOW); digitalWrite(LED_DAY,LOW); if(Serial.available()>=21){ // tot el que entri a partir d'aqui serà valid. if(Serial.read()==0x7E){ //Encén el LED per indicar quan es reben dades digitalWrite(debugLED, HIGH); delay(10); digitalWrite(debugLED,LOW);  

// legeix les variables que no estem utilitzant
for (int i = 0; i<18; i++) { byte discard = Serial.read(); } int analogHigh = Serial.read(); int analogLow = Serial.read(); analogValue = analogLow + (analogHigh * 256); } } if(analogValue > 0 && analogValue <= 350){ digitalWrite(LED_NIGHT, HIGH); delay(10); digitalWrite(LED_NIGHT, LOW); //LCD lcd.clear(); lcd.setCursor(7,0); lcd.print("MORNING"); // ‘MORNING’es mostra per pantalla } if(analogValue > 350 && analogValue <= 750){ digitalWrite(LED_SUNSET, HIGH); delay(10); digitalWrite(LED_SUNSET, LOW); //LCD lcd.clear(); lcd.setCursor(7,0); lcd.print("AFTERNOON"); //‘AFTERNOON’es mostra per pantalla } if(analogValue>750 && analogValue<=1023){ digitalWrite(LED_DAY, HIGH); delay(10); digitalWrite(LED_DAY, LOW); //LCD lcd.clear(); lcd.setCursor(7,0); lcd.print("NIGH"); // ‘NIGH’es mostra per pantalla } }

3. Demostració







domingo, 18 de mayo de 2014

Lab 5.1: Sensors and Actuators

Per Aurora Ripoll i Jose Ángel Mohedano


OBJECTIU: Mitjançant la comunicació inal·làmbrica de dues XBees, connectar sensors i actuadors.


Controlarem el llum d'un LED mitjançant dos sensors, un LDR i un botó, i quatre actuadors, un LED groc de llum, un LED blau que indica el control manual d'aquesta, un LED vermell que indica el control automàtic i un interruptor per controlar la llum del LED de manera manual. Per defecte la llum s'anirà regulant amb el sensor de llum LDR segons la quantitat de llum que hi hagi. Quant el control d'aquesta es vulgui fer manualment s'haurà d'activar el botó, el qual permetrà que la llum sigui regulada mitjançant l'ús d'un interruptor. Cada cop que es canvi de mode s'encendran els LED's d'estat corresponent.



  1. Quant premem el botó, variem el valor de una variable booleana; segons aquest encenem un led o altre indicant així en l'estat en el que ens trobem.
  2. Després per alimentar la llum tenim dos camins(segons si estem en MAN o AUTO); un per on arriben els valors corresponents segons el valor del LDR, i l'altre on ens trobem un interruptor que tanca o obre el circuit. Aquests dos camins no estan continuament enviant informació, únicament s'activen en el cas de trobar-se en l'estat en qüestió.


    • En el cas de trobar-nos en l'estat AUTOMÀTIC utilitzarem una SORTIDA ANALÒGICA
    • En el cas de trobarnos en l'estat MANUAL utilitzarem una SORTIDA DIGITAL


Material necessari:



  • Placa Arduino UNO
  • Placa Arduino Micro Pro
  • Placa Protoboard (x2)
  • XBees Explorer (x2)
  • Digi XBee (x2)
  • Cables connectors
  • Resistències:10(x3),12, 22 kOhms.
  • Botó 
  • LDR
  • LED's (x3)




1. Muntatge del circuit

  • Sensor


1) Muntatge del circuit



  • Actuador




2. Disseny del codi

  • Sensor



int BUTTON = 2; // Pin digital del boto int LDR_value; int LDR_pin = 0; // Pin analogic de l'LDR boolean autom = false; // variable "mode" void setup(){ pinMode(BUTTON, INPUT); pinMode(LDR_pin, INPUT); Serial.begin(9600);
} void loop(){ // emmagatzemem la quantitat de llum rebuda per l'LDR a la variable LDR_value LDR_value = analogRead(LDR_pin); if(autom==false){ // MODE MANUAL Serial.print('Z'); // S'envien Z delay(50); // quant es prem el boto, es canvia al mode automatic if(digitalRead(BUTTON) == HIGH){ autom=true; delay(500); } } if(autom==true){ // MODE AUTOMATIC // Pels diferents valors de LDR_value s'envien diferents lletres: // Quant LDR_value<128, s'enviar una A if(LDR_value<128){ Serial.print('A'); delay(50); } //Quant 128<LDR_value<256, s'enviar una B if(LDR_value>128 && LDR_value<256){ Serial.print('B'); delay(50); } //Quant 256<LDR_value<384, s'enviar una C if(LDR_value>256 && LDR_value<384){ Serial.print('C'); delay(50); } //Quant 384<LDR_value<512, s'enviar una D if(LDR_value>384 && LDR_value<512){ Serial.print('D'); delay(50); } //Quant 512<LDR_value<640, s'enviar una E if(LDR_value>512 && LDR_value<640){ Serial.print('E'); delay(50); } // quant es prem el boto, es canvia al mode manual if(digitalRead(BUTTON) == HIGH){
autom=false; delay(500); } } }



  • Actuador

int LED1=5;
int LED2=3;
int LED_auto=7;
int LED_manual=8;
char missatge;


void setup(){

    pinMode(LED1,OUTPUT);
    pinMode(LED2,OUTPUT);
    pinMode(LED_auto,OUTPUT);
    pinMode(LED_manual,OUTPUT);
    
    Serial1.begin(9600);
}

void loop(){

    if(Serial1.available()>0){
      
     
      missatge = Serial1.read();
      
      
      // Interpretacio de les dades rebudes:
      
      
      // Si rebem una Z, mode manual:
      
      if (missatge == 'Z'){

        pinMode(LED1,INPUT);
        pinMode(LED2,OUTPUT);
        analogWrite(LED1, 0);
        digitalWrite(LED2, HIGH);
        digitalWrite(LED_manual, HIGH);
        digitalWrite(LED_auto, LOW);
        delay(30);


      }
      
      // si rebem qualsevol altre cosa, mode automatic:
      
      else {
        
        digitalWrite(LED_auto, HIGH);
        digitalWrite(LED_manual, LOW);
        digitalWrite(LED2, LOW);
        Serial.print(Serial1.read());

      // Regulem la intensitat de llum segons la lletra rebuda:

        
            if(missatge=='A')
            {    
                            
              analogWrite(LED1, 0);
              delay(50);
              
            }
            
            if(missatge=='B')
            {    
                            
              analogWrite(LED1, 64);
              delay(50);

            }
            
            if(missatge=='C')
            {    
                           
              analogWrite(LED1, 128);
              delay(50);

            }
            
            if(missatge=='D')
            {    
                            
              analogWrite(LED1, 192);
              delay(50);
              
            }
            
            if(missatge=='E')
            {    
                           
              analogWrite(LED1, 255);
              delay(50);
              
            }
            
      }
    }
  }





3. Demostració:




4. Problemes:

En un inici volíem crear un laboratori que ens enfoqués més cap al projecte final de l'assignatura; controlar un servo-motor mitjançant un potenciòmetre de forma remota.
En principi no semblava tan difícil, però tot i aplicar la teoria tal i com la teniem entesa, veiem que el servo-motor actuava de forma aleatòria segons movíem la protoboard; després ens varem adonar de que el valor variava segons la distancia amb la taula(sota la protoboard tenim enganxada una placa aparentment d'alumini que creiem que es la culpable).

Un cop ens vam canviar de protoboard vam veure que el servo-motor no "entenia" directament les dades que sortien del potenciòmetre, amb la qual cosa buscant, vam trobar una funció de conversió de dades: la funció map(ValInMin,valInMax,valOutMin,ValOutMax).
Tot i així no vam trobar un resultat satisfactori amb el que es veigués un control precís del servo-motor.
Per tant vam decidir canviar a un projecte, aparentment més senzill.(jajaja):  un exemple de control domòtic del llum de la llar. 

Això ens va portar cap al mateix punt, una conversió de dades del LDR al LED, portant-nos a una mateixa falta de precisió, fins que amb l'ajuda del nostre professorat vam poder donar-li valors fixos al LED, introduint lletres A-E. D'aquesta manera obtenim una precisió segons diferents barems del LDR, variant la intensitat del LED.