Archive for Arduino

De GuyGuyplex

De GuyGuyplex is een knutsel apparaat wat ik gemaakt heb voor een jongen van 8 jaar. Hij is erg slim en verveeld zich dood op school. De school kan hem niet de lesstof bieden die een uitdaging voor hem is. Maar natuurlijk wil je ook niet al te veel opvallen in de klas en al te veel anders zijn dus wat doe je dan? Misschien wel niet al te veel opvallen en je dood vervelen.

Veel hoogbegaafde kinderen hebben last van faal angst. Dat komt omdat ze nooit om hebben leren gaan met falen. Want ze snappen alles zo snel. Als er dan iets is wat ze niet snappen dan weten ze niet goed hoe ze met die gevoelens om moeten gaan. Met dit in mijn hoofd heb ik de GuyGuyplex ook gemaakt. Er zitten een paar spelletjes in die een hoge mate van aanzetten en gelijk werken hebben, maar ze bieden ook een uitdaging.

GuyGuyplex kit

Maze: Maze is een spel waarbij je door een doolhof moet lopen naar de uitgang. Je kan alleen het stukje van het doolhof zien waar je staat en het is een beetje mistig in het doolhof dus je kan maar 3 stappen ver zien. Aan het begin van het doolhof hangt een kaart die je 5 seconden lang kan zien (als het doolhof te groot wordt zie je maar een deel). Elke keer dat je het doolhof door bent groeit het 10×10, 15×15, 20×20 enz tot 60×60 en geeft het een aanmoedigende boodschap voor de volgende ronde. De doolhoven zijn elke keer anders. De speler zal in zijn hoofd moeten bijhouden hoe de kaart er uit ziet en zo de uitgang vinden.

Pong: het bekende tennis spelletje. Maar je kan het niet gelijk spelen. Eerst moet je een schuif weerstand aansluiten zodat je je batje heen en weer kan bewegen. Dat doe je met draadjes en een schroevendraaier. Dus daar begint het geknutsel al.

Space invaders: het bekende spaceinvaders spelletje. Maar ook hier moet je de schuifweerstand aansluiten. Maar je moet ook kunnen schieten en daarvoor kan je een klop sensor aansluiten zodat je schiet als je op de sensor slaat of als je wat ingewikkelder doet kan je met een weerstand en een schakelaar een gewone vuurknop maken. Maarja zo’n schuifweerstand en schakelaartje houd moeilijk vast. Dus dat geeft weer de uitdaging om een game console te maken van karton zodat je het allemaal beter kan vasthouden.

Er is een afstandsbediening waar je de relais mee kan bedienen en rare geluiden maken. Er zit een orgel programma in waar je met een lichtsensor (LDR) geluid met licht kan maken. Game of life zit er ook in. Er is een programma scope wat een scope op het scherm tovert. Je kan er werkelijk spanning mee meten maar dan moet je wel al het rekenwerk zelf doen. Het display is niet grootgenoeg om de waardes in decimale getallen te laten zien dus je ziet ze in binair boven en onder aan het scherm. Maar je hoeft helemaal niet zo ingewikkeld te doen om lol te hebben met de scope je kan triggers instellen met hysteresis zodat je de relais kan laten schakelen door de sensors die je er  op aan kan sluiten.

Er zit een alarm doosje bij wat een vreselijk iritante sirene kan maken, en wat je op de relais aan kan sluiten om zo een alarm te maken. Bijvoorbeeld als er op de deur geklopt word, met het piezo sensor.

Er zit ook een kleine breadboard op waar je met weerstanden en transistors schakelingetjes kan bouwen. Het is ook een prima plek voor het aansluiten van de sensors. Er zit een boekje bij met allemaal schakelingen en een uitgebreide uitleg. 

P3210601

Maarja als je ouder wordt dan gaat ook dit natuurlijk op een gegeven moment vervelen dus dan kan je de computer aansluiten en de bestaande programma’s veranderen of nieuwe programma’s in de arduino laden die het hart vormt van de GuyGuyplex.

En als je dan nog verder bent dan ga je gewoon je eigen programma’s maken.

En zo bied dit apparaat een blijvende uitdaging voor de creatieve geest.

Ik heb niet echt een schema gemaakt van dit project. Het is allemaal heel simpel. Alle uitgangen/ingangen hebben een 330 ohm weerstand in serie zodat je erg veel moeite moet doen om de arduino stuk te krijgen. De relais worden geschakeld met een transistor die naar de Vraw gaat. De relais doen het dus alleen als er een externe voeding is aangesloten en niet via de usb poort. Het IR sensor is er een met een ingebouwde demodulator, uit een videorecorder gesloopt. Uit de source code blijkt het schema en alle pinnen die gebruikt worden zijn met een #define aangegeven.

Onderaan komen links naar de manual en source code.

Auto Pilot

This article is about my auto pilot project for my sailing boat. First I wanted to buy a Rayteon SPX or ST6000 series AP but those things are expensive. Next The ST4000+ was on my list but still those go for prices above what I could afford. So I saw someone on the web who build his own AP. He never published any code though, and I want my own litle features.

For you non techies just scroll down to the next article…

So what are those features? I want to be able to use it next to my st3000 that still works. To control it by Ipad or maybe by my kobo reader, better viewable in sunlight. To control it by bluetooth with the peble watch. To be able to steer by a windvane ove NMEA (need to get one this winter). To tack with a maximum yaw, so to steer higher than normally would be done and prevent too much yaw (I am a pleasure boat sailor and want to keep ik fun and not fight). And ofcource just set a cource and go there and maybe waypoints. And if it works with the peble an overboard alarm is the bluetooth connection is suddenly lost so to steer to a stop.

The hardware consists out of a motor driver, a compass module and a pc that can later on in the project be replaced by a mcu. The compass module consists of an CMP01 module and an arduino and a rs232 driver with a power supply. The compass module gives the compass readings in 3600 counts and yaw (+/- 85 degrees) and tilt (+/-) 85 degrees, and is yaw and tilt compensated. The driver module consists of a FET driver board (pololu 36V20CS) max 36Volt 20Amp with coasting capability. The coasting is a feature to be able to turn the motor by hand is the board is enabled but not driving, normally a board like that has the motot in that case in break. A 20 amp driver is overkill but the costs of the driver board are lower than a less heavy one and it leaves room for other driving hardware in the future. The driver board also has nice features as error checking and measuring the current through the motor.The driver board is controlled by an arduino and also has a rs232 driver and power supply.

Both the modules are connected to a boat pc. The boat pc takes less than 10W and consists of a DN2800MT NM10 mini-ITX board with two Kingston SODIMM DDR3-1066 2GB modules and an 128GB SSD. It runs windows 7 and the development enviroment on it is Labview and VB6. It is hooked up to an wifi router so I can control it wit my iPad over a VNC connection. At this moment I also have a gps module connected to it. The board has two build in rs232 ports so I have to get an extra one. If you want to use the rs232 ports for powered devices over pin 9 you also have to connect pin 5 to the real ground. The pin 5 is connected to the ground through a resistor.

IMG 0904

The whole computer including router uses 0.91A from my battery (14.58V) with a 20% cpu load. That is not bad I would say. That is measured with my BMV602S battery monitor.

the compass code:

/****************************************************************
* Arduino CMPS10 example code *
* CMPS10 running I2C mode *
* by James Henderson, 2012 *
* Modified by Jelbert Holtrop, 2012 *
*****************************************************************/
#include <Wire.h>
#include <SoftwareSerial.h>

#define ADDRESS 0x60 // Defines address of CMPS10

void setup(){
Wire.begin(); // Conects I2C
Serial.begin(9600);
// Serial.println("Compass unit 1");

}

void loop()
{
sendData();
}

void sendData()
{
byte highByte, lowByte, fine,
accelXh,accelXl,accelYh,accelYl,accelZh,accelZl; // highByte and lowByte store high and low bytes of the bearing and fine stores decimal place of bearing
char pitch, roll, dummy; // Stores pitch and roll values of CMPS10, chars are used because they support signed value
int bearing, accelX, accelY, accelZ, crc; // Stores full bearing

Wire.beginTransmission(ADDRESS); //starts communication with CMPS10
Wire.write(2); //Sends the register we wish to start reading from
Wire.endTransmission();

Wire.requestFrom(ADDRESS, 4); // Request 4 bytes from CMPS10
while(Wire.available() < 4); // Wait for bytes to become available
highByte = Wire.read();
lowByte = Wire.read();
pitch = Wire.read();
roll = Wire.read();
bearing = ((highByte<<8)+lowByte)/10; // Calculate full bearing
fine = ((highByte<<8)+lowByte)%10; // Calculate decimal place of bearing

Serial.print(bearing,DEC);
Serial.print(".");
Serial.print(fine,DEC);
Serial.print(",");
Serial.print(pitch,DEC);
Serial.print(",");
Serial.print(roll,DEC);
crc=abs(bearing)+abs(pitch)+abs(roll)+10; //hele simple crc + lege string detectie
Serial.print(",");
Serial.print(crc,DEC);
Serial.println(" ");
}

 

Hmm some of the formatting is gone bu you get the idea.

Next the code of the driver. This code now includes for reading the motor current and voltage. Added options for continious pwm drive and set deadband.

//program board Duemilanove w/ Atmega 328 com 1

int DIR=3;
int PWML=5;
int PWMH=6;
int CS=A0;
int FF1=8;
int FF2=9;
int command=0;
int halfspeed=127;
int fullspeed=255;
int err1;
int err2;
int rotation=0;
int deadBand=0;

void setup()
{
 // drive/coast PWML=PWMH DIR=DIRECTION
 // drive/brake-low PWMH=0 DIR=direction
 // drive/brake-high PWML=0 Dir=direction
 // coast=lowpower PWMH=PWML=0 DIR=x
   pinMode(DIR, OUTPUT);  //analogwrite(ledpin,value) pwm zet pinmode zelf
 //  pinmode(PWML, OUTPUT);
 //  pinmode(PWMH, OUTPUT);

 //  pinmode(CS, INPUT); //voor analoge pinnen is dat niet nodig
   pinMode(FF1, INPUT);
   pinMode(FF2, INPUT);

 Serial.begin(9600); 
 Serial.print("Version 1 beta");
// establishContact();  // send a byte to establish contact until receiver responds 

}

void loop()
{
  int MotorCurrent;
  int MotorVoltage;
  int MaxCurrent;
    if(Serial.available()>0)
    {
      //Commands
      // drive/coast 50%=A 100%=B  : PWML=PWMH DIR=DIRECTION
      // drive/break 50%=C 100%=D  : drive/brake-high PWML=0 Dir=direction
      // Direction L,R 
      // COAST Z                   : coast=lowpower PWMH=PWML=0 DIR=x
      command=Serial.read();
      Serial.print(command); //echo
      switch (command)
      {
        case 'A':
          //max motor current = 8
          MaxCurrent=8;
          analogWrite(PWML,halfspeed);
          analogWrite(PWMH,halfspeed);
          break;
        case 'B':
          //max motor current = 19
          MaxCurrent=19;
          analogWrite(PWML,fullspeed);
          analogWrite(PWMH,fullspeed);
          break;
        case 'C':
        //max motor current = 10
          MaxCurrent=10;
          analogWrite(PWML,halfspeed);
          analogWrite(PWMH,0);
          break;
        case 'D':
        //max motor current = 17
          MaxCurrent=17;
          analogWrite(PWML,fullspeed);
          analogWrite(PWMH,0);
          break;
        case 'L':
          digitalWrite(DIR,HIGH);
          break;
        case 'R':
          digitalWrite(DIR,LOW);
          break;
        case 'P':
        //continious pwm
          rotation=constrain(rotation,-255,255);
          rotation=Serial.parseInt();
          if(abs(rotation)<deadBand)
            {
              analogWrite(PWML,0);
              analogWrite(PWMH,0);
              break;
            }
          if(rotation>0) 
            digitalWrite(DIR,HIGH); 
           else 
            digitalWrite(DIR,LOW);
          rotation=abs(rotation);
          analogWrite(PWML,rotation);
          analogWrite(PWMH,rotation);
          break;
        case 'W':
        //set deadband The ammount of pwm value that results in no rotation. 
        //to make sure the motor is not continually working with low values of pwm
        deadBand=Serial.parseInt();
        break;
        case 'Z':
          analogWrite(PWML,0);
          analogWrite(PWMH,0);
          digitalWrite(DIR,LOW);
          break;

      }
    }   
      err1 = digitalRead(FF1);
      err2 = digitalRead(FF2);
      if (err1 == HIGH && err2 == HIGH) Serial.println("ERROR: UnderVoltager");
      if (err1 == HIGH && err2 == LOW)  Serial.println("ERROR: OverTemprature");
      if (err1 == LOW && err2 == HIGH)  Serial.println("ERROR: ShortCircuit, need to reset");
// hier nog de code voor het uitlezen en weergeven van stroom en spanning I=I-470  
// Motor current sense zit op A0
// Waar zit motor voltage sense ook al weer op A1?
  MotorCurrent=analogRead(CS)-471;
  MotorVoltage=analogRead(A1);
  //Serial.print("Motor current=");
  Serial.print(MotorCurrent,DEC);
  Serial.print(",");
  //Serial.print("Motor voltage=");
  Serial.println(MotorVoltage,DEC);
  /*if (abs(MotorCurrent)>=MaxCurrent)
  {// put motor in Z = off, coast
          analogWrite(PWML,0);
          analogWrite(PWMH,0);
          digitalWrite(DIR,LOW);

  }*/
}

void establishContact() {
  while (Serial.available() <= 0) {
    Serial.println("Hello");   // send an initial string
    delay(300);
  }
}

 

So far for now but as the project has progress I will add to this post. Publisching labview code is very unpractical so for that I should find some solution.

Creative Commons License
This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License.