donderdag 29 maart 2012

RC besturing

Het leek mij een leuk idee om mijn robot met mijn RC besturing te kunnen besturen. Het programma is vrij eenvoudig gehouden: eerst wordt er drie seconden gewacht, zodat de ontvanger kan opstarten en de mogelijkheid heeft om verbinding te maken met de zender. Vervolgens worden er twee 'while()' lussen doorlopen: de eerste voor het geval dat er nog een puls "bezig" is (poort B0 op 0), de tweede om te zorgen dat de derde lus, die de meting moet doen, precies op de flank van de pus kan beginnen tellen.
Ook die laatste werkt zeer eenvoudig: zolang dat B0 door de puls naar nul getrokken wordt, wordt per 10us (slechts een honderdduizendste van een seconde!) RC[1] met ééntje verhoogd.
Als vervolgens de puls eindigt en B0 opnieuw '1' wordt, wordt er uit de lus gesprongen, om met een bijna identiek systeem de andere puls op B1 ook te meten.

Vervolgens worden de waardes (lengte van de pulsen) naar het LCD geschreven, en krijgen ook de motoren de nodige instructies: momenteel heb ik het zo geprogrammeerd dat de motoren met twee snelheden kunnen draaien, zodat het ook mogelijk is om een flauwe bocht te maken.
Om de lengte van de pulsen te kennen in us, hoef je enkel de waardes op het LCD te vermenigvuldigen met tien.

De schakeling op het breadboard is vrij eenvoudig: de twee draden van de ontvanger sturen twee NPN transistors aan.  Deze simuleren een drukschakelaar, zodat met de PULL-UP (3,9KOhm) weerstand de Vout aan te sturen is met een digitaal 1/0 signaal. De ontvanger is met de - en + ingeplugd in de uitbreidingsconnector, vervolgens zijn kanaal 7 en 8 via de de lange zwarte en rode draad met het breadboard verbonden.

!!!
Het kan zijn dat je zender niet ingesteld staat om de uiterste waardes te geven. Pas dit aan op je zender of in het progamma. Anders zal de puls minder variëren, bv. i.p.v. van 820us tot 1900us slechts van 1000us tot 1720us.

Nog met dank aan Francis van het Dwengo team voor de hulp bij het schrijven in C en het gratis vervangen van de motorcontroller.



Het programma:

#include <dwengoBoard.h>
#include <dwengoConfig.h>
#include <dwengoDelay.h>
#include <dwengoLCD.h>
#include <dwengoMotor.h>

#define B0          PORTBbits.RB0 //Ingangen doorverwijzen.
#define B1          PORTBbits.RB1

void main(void) {

  int RC[2];        //Variabelen voor tijdsduur pulsen.

  initBoard();
  initLCD();
  initMotor();

  backlightOn();

  printStringToLCD("Initializing...", 0, 0);
  delay_s(3);       //De ontvanger de tijd geven om op te starten.
 

  while (TRUE) {

       //Programma om lengte puls op B0 te meten.
       while (B0 == 0) {          //Indien aan.
       }

       while (B0 == 1) {          //Indien uit.
       }

       while (B0 == 0) {          //Indien aan.
         RC[1]+=1;
         delay_us(10);
       }

       //Programma om lengte puls op B1 te meten.
       while (B1 == 0) {          //Indien aan.
       }

       while (B1 == 1) {          //Indien uit.
       }

       while (B1 == 0) {          //Indien aan.
         RC[2]+=1;
         delay_us(10);
       }

       //Waardes naar LCD schrijven.
       clearLCD();
       printIntToLCD(RC[1], 0, 0);
       printIntToLCD(RC[2], 0, 9);

       //Besturing motor 1.
       if (RC[1] > 166) {
         if (RC[1] > 181) {
             setSpeedMotor1(1023);
         }
         else {
             setSpeedMotor1(600);
         }
       }
       else if ((RC[1] < 167) && (RC[1] > 106)) {
         setSpeedMotor1(0);
       }
       else if (RC[1] < 107) {
         if (RC[1] < 92) {
             setSpeedMotor1(-1023);
         }
         else {
             setSpeedMotor1(-600);
         }
       }

       //Besturing motor 2.
       if (RC[2] > 166) {
         if (RC[2] > 181) {
             setSpeedMotor2(-1023);
         }
         else {
             setSpeedMotor2(-600);
         }
       }
       else if ((RC[2] < 167) && (RC[2] > 106)) {
         setSpeedMotor2(0);
       }
       else if (RC[2] < 107) {
         if (RC[2] < 92) {
             setSpeedMotor2(1023);
         }
         else {
             setSpeedMotor2(600);
         }
       }


       //'RC' resetten op nul.
       RC[1] = 0;  
       RC[2] = 0;

       //Tijdsduur lus (verlaag voor een snellere reactietijd).
       delay_ms(250);

  }   
}

maandag 19 maart 2012

Extra sensors

De antibotsbot werkt ondertuseen zeer goed, maar op smalle plekken rijdt hij soms nog tijdens het achteruitrijden tegen de muur. Om dit te verhelpen, zal de robot twee extra sensors krijgen, namelijk achteraan: zo kan hij precies zien wat de afstand is met de muur.

Bij het robot startpakket van Dwengo had ik nog extra sensoren bijbesteld, deze waren echter nog niet aangesloten. Zodus heb ik ze op een printje gesoldeerd, en na enig schrijen in C ze werkend gekregen: dit was niet zo makkelijk, want de werking van de sensormodule mocht niet gestoord worden.


De Vout - pin van de fototransistor is aangeslotenop A3, de sturing voor de IR LED op E0. Merk op dat de waarde van de sensor door vier gedeeld wordt: de sensors op de module gaan maar tot en met 255, de extra sensor op A3 tot en met 1023. Ook wordt er ter vergelijking nog de sensor OS6 van het sensorbord op regel twee van het LCD weergegeven.

De sensor

Het (eenvoudige) programmaatje:

#include <dwengoBoard.h>
#include <dwengoConfig.h>
#include <dwengoADC.h>
#include <dwengoLCD.h>
#include <dwengoDelay.h>
#include <dwengoSensorModule.h>

#define IRLED PORTE     //Doorverwijzingen.
#define AF 0b00
#define AAN 0b11

void main(void) {

     int AMBIENT;
     int ACTIVE;

    TRISE = 0;     //Definieer poorten E0 en E1 als uitgang.

    initBoard();
     initLCD();
    initADC();
     initSensorModule();
    backlightOn();

    while(TRUE) {

      AMBIENT = readADC(3);

       IRLED = AAN;
      ACTIVE = readADC(3);
       IRLED = AF;

       clearLCD();
       printIntToLCD(((AMBIENT - ACTIVE)/4), 0, 0);
       printIntToLCD(readSensor(OS6, DIFF_MODE), 1, 0);
       //Geef ook waarde extra sensor ter vergelijking.

       delay_ms(250);
    }
}