Archiv der Kategorie: Mikrocontroller

Arduino Roboter mit USB Host Shield (1)

Aufgabenstellung

Es wird eine Lösung benötigt, um einen Arduino Microcontroller als USB Host zu betreiben, welcher selber die Stromversorgung der angeschlossenen USB-Geräte übernimmt. Für die einfache Erweiterung des Bausatzes existieren sogenannte „Shields“, welche eine preiswerte Lösung ohne die Notwendigkeit eines eigenen Platinenentwurfs zur Verfügung stellen.

Ansatz

Durch die Verwendung des USB Host Shields von DFRobot.com lässt sich über eine Aufsteckvariante über die SPI Schnittstelle und existierender, fertiger Bibliotheken eine solche Konfiguration schnell umsetzen.

Im Nachfolgebeispiel wird der bereits existierende Roboter (siehe Kategorie Mikrocontroller) mit einem Arduino Duemilanove (Arduino UNO kombatibel) und dem USB Host Shield ausgestattet. Dieser wird über eine USB Tastatur gesteuert.

Lösung

Arduino Duemilanove mit USB Host Shield (Pan&Tilt Servos, Tamiya Twin Motor Gear Box…)

Code

Der Code benutzt die downloadbare Bibliothek des USB Host Shields, welche sich nach dem Kopieren in die Arduino IDE verwenden lässt. Darüber hinaus wird der Pan and Tilt Servo über die Servo-Bibliothek gesteuert.

#include <avr/pgmspace.h>

#include <avrpins.h>
#include <max3421e.h>
#include <usbhost.h>
#include <usb_ch9.h>
#include <Usb.h>
#include <usbhub.h>
#include <avr/pgmspace.h>
#include <address.h>
#include <hidboot.h>

#include <printhex.h>
#include <message.h>
#include <hexdump.h>
#include <parsetools.h>

#include <Servo.h> 

int E1 = 6; //M1 Speed Control
int E2 = 5; //M2 Speed Control
int M1 = 8; //M1 Direction Control
int M2 = 7; //M2 Direction Control

 
Servo myservo;  // create servo object to control a servo 
Servo myservo2;  // create servo object to control a servo 
int horizontal=64;
int vertical=64;

boolean servoLeft = false;
boolean servoRight = false;
boolean servoUp = false;
boolean servoDown = false;


class KbdRptParser : public KeyboardReportParser
{
        void PrintKey(uint8_t mod, uint8_t key);
        
protected:
	virtual void OnKeyDown	(uint8_t mod, uint8_t key);
	virtual void OnKeyUp	(uint8_t mod, uint8_t key);
	virtual void OnKeyPressed(uint8_t key);
};

void KbdRptParser::PrintKey(uint8_t m, uint8_t key)	
{
    MODIFIERKEYS mod;
    *((uint8_t*)&mod) = m;
    Serial.print((mod.bmLeftCtrl   == 1) ? "C" : " ");
    Serial.print((mod.bmLeftShift  == 1) ? "S" : " ");
    Serial.print((mod.bmLeftAlt    == 1) ? "A" : " ");
    Serial.print((mod.bmLeftGUI    == 1) ? "G" : " ");
    
    Serial.print(" >");
    PrintHex<uint8_t>(key);
    Serial.print("< ");

    Serial.print((mod.bmRightCtrl   == 1) ? "C" : " ");
    Serial.print((mod.bmRightShift  == 1) ? "S" : " ");
    Serial.print((mod.bmRightAlt    == 1) ? "A" : " ");
    Serial.println((mod.bmRightGUI    == 1) ? "G" : " ");
};

void KbdRptParser::OnKeyDown(uint8_t mod, uint8_t key)	
{
    Serial.print("DN ");
    PrintKey(mod, key);
    uint8_t c = OemToAscii(mod, key);
    
    
    int leftspeed = 255; //255 is maximum speed
    int rightspeed = 255;      
    
    switch(key)
    {
       case 0x50:
       {
          horizontal-=10;
       }
       break;
       case 0x4F:
       {
          horizontal+=10;
       }
       break;       
       case 0x52:
       {
          vertical-=10;
       }
       break;       
       case 0x51:
       {
          vertical+=10;
       }
       break;             
       case 0x5C:
       {
           left (leftspeed,rightspeed);
       }
       break;
       case 0x5E:
       {
           right (leftspeed,rightspeed);
       }
       break;
       case 0x60:
       {
           forward (leftspeed,rightspeed);
       }
       break;
       case 0x5A:
       {
           reverse (leftspeed,rightspeed);
       }
       break;   
       case 0x5D:
       {
           stop();
       }
       break;          
    }  
    
    if (horizontal <= 1 || horizontal >=128) horizontal=64;    
    if (vertical <= 1 || vertical >=128) vertical=64;    
    
    if (c)
        OnKeyPressed(c);
}

void KbdRptParser::OnKeyUp(uint8_t mod, uint8_t key)	
{
    Serial.print("UP ");
    
    
  
    
    PrintKey(mod, key);
}

void KbdRptParser::OnKeyPressed(uint8_t key)	
{
    Serial.print("ASCII: ");
    Serial.println((char)key);
};

USB     Usb;
//USBHub     Hub(&Usb);
HIDBoot<HID_PROTOCOL_KEYBOARD>    Keyboard(&Usb);

uint32_t next_time;

KbdRptParser Prs;

void setup()
{
    // attaches the servo on pin 2 to the servo object 
    myservo.attach(2);  

    // attaches the servo on pin 3 to the servo object 
    myservo2.attach(3);  
  
    Serial.begin( 9600 );
    Serial.println("Start");

    if (Usb.Init() == -1)
        Serial.println("OSC did not start.");
      
    delay( 200 );
  
    next_time = millis() + 5000;
  
    Keyboard.SetReportParser(0, (HIDReportParser*)&Prs);
}



void loop()
{
  /*
    if(servoLeft) horizontal-=10;
    if(servoRight) horizontal+=10;
    if(servoUp) vertical-=10;
    if(servoDown) vertical+=10;    
    */
    
// sets the servo position according to the scaled value 
    myservo.write(horizontal);                

// sets the servo position according to the scaled value  
    myservo2.write(vertical);                  
    
    Serial.println("Horizontal: "+horizontal );
    Serial.println("Vertical: "+vertical );
      
  
    Usb.Task();
}

void stop(void) //Stop
{
  digitalWrite(E1,LOW);
  digitalWrite(E2,LOW);
}
void forward(char a,char b)
{
  analogWrite (E1,a);
  digitalWrite(M1,LOW);
  analogWrite (E2,b);
  digitalWrite(M2,LOW);
}
void reverse (char a,char b)
{
  analogWrite (E1,a);
  digitalWrite(M1,HIGH);
  analogWrite (E2,b);
  digitalWrite(M2,HIGH);
}

void left (char a,char b)
{
  analogWrite (E1,a);
  digitalWrite(M1,HIGH);
  analogWrite (E2,b);
  digitalWrite(M2,LOW);
}

void right (char a,char b)
{
  analogWrite (E1,a);
  digitalWrite(M1,LOW);
  analogWrite (E2,b);
  digitalWrite(M2,HIGH);
}

Projektvorstellung: Microcontrollerbasierter Roboter mit Infrarotsensor (1) und -entfernungsmesser (2)

Aufgabenstellung

Für die Steuerung kabelloser Geräte (wie z.B. Elektromotoren) wird eine programmierbare, batteriebetriebene Lösung gesucht, die Eingabewerte von Sensoren annehmen und verarbeiten kann.

Ansatz

Durch die Verwendung des programmierbaren Arduino-Boards (arduino.cc) können Motoren mit niedriger Spannung bis zu 5 Volt betrieben werden.

Lösung

Projekt 1: Infrarotsensor

Projekt 2: Entfernungsmesser

Zusammenstellung des Roboters (Projekt 1)

Die folgenden Hardware-Komponenten werden benutzt:

  • Tamiya Track&Wheel Set
  • Tamiya Twin-Motor Gear Box (Motorkonfiguration: Type C)
  • Platine DFRobotShop Rover
    • Arduino Duemilanove; Prozessor ATMega 328
    • integrierter Motorcontroller (besetzt Pins 5-8)
    • USB Schnittstelle
    • Battery-Fach
  • Infrarotsensor: DFR0094

Zusammenstellung des Roboters (Projekt 2)

Die folgenden Hardware-Komponenten werden benutzt:

  • Tamiya Track&Wheel Set
  • Tamiya Twin-Motor Gear Box (Motorkonfiguration: Type C)
  • Platine DFRobotShop Rover
    • Arduino Duemilanove; Prozessor ATMega 328
    • integrierter Motorcontroller (besetzt Pins 5-8)
    • USB Schnittstelle
    • Battery-Fach
  • IR Range Sensor: SHARP GP2D12 IR Ranger Sensor

Verdrahtung des Roboters (Projekt 1)

Infrarotsensor:

  • Arduino 5V wird an VCC des Sensors angeschlossen
  • Arduino GND an Infrarotsensor GND
  • D wird (hier in meinem Code) auf Digital Pin 11 gelegt

Die folgenden Software-Komponenten werden benutzt:

  • IDE von Arduino CC
  • Infrarot-Bibliothek: IRremote.h

Verdrahtung des Roboters (Projekt 2)

Infrarotsensor:

  • Arduino 5V mit IR Ranger Sensor roter Draht verbinden
  • Arduino GND mit IR Ranger Sensor schwarzer Draht verbinden
  • Arduino A2 analoger Eingang mit grünem Draht verbinden

Die folgenden Software-Komponenten werden benutzt:

  • IDE von Arduino CC

Mein Code (Projekt 1)


#include <IRremote.h> // use the library

int E1 = 6; //M1 Speed Control
int E2 = 5; //M2 Speed Control
int M1 = 8; //M1 Direction Control
int M2 = 7; //M2 Direction Control

int receiver = 11; // pin 1 of IR receiver to Arduino digital pin 11

IRrecv irrecv(receiver); // create instance of 'irrecv'

decode_results results;

void setup()
{
  int i;
  for(i=5;i<=8;i++)
  pinMode(i, OUTPUT);  
  Serial.begin(9600); // for serial monitor output
  irrecv.enableIRIn(); // Start the receiver
}

void loop()

{

  if (irrecv.decode(&results)) // have we received an IR signal?
  {

    Serial.println(results.value, HEX); // display it on serial monitor in hexadecimal
    
    int leftspeed = 255; //255 is maximum speed
    int rightspeed = 255;    
    switch(results.value)
    {
      case 0x802:
      {
        forward (leftspeed,rightspeed);
      }
      break;
      case 0x804:
      {
        left (leftspeed,rightspeed);
      }
      break;    
      case 0x806:
      {
        right (leftspeed,rightspeed);
      }
      break;    
      case 0x808:
      {
        reverse (leftspeed,rightspeed);
      }
      break;      
      default:
        stop();
      break;
    }

    irrecv.resume(); // receive the next value

  }  // Your loop can do other things while waiting for an IR command

}

void stop(void) //Stop
{
  digitalWrite(E1,LOW);
  digitalWrite(E2,LOW);
}
void forward(char a,char b)
{
  analogWrite (E1,a);
  digitalWrite(M1,LOW);
  analogWrite (E2,b);
  digitalWrite(M2,LOW);
}
void reverse (char a,char b)
{
  analogWrite (E1,a);
  digitalWrite(M1,HIGH);
  analogWrite (E2,b);
  digitalWrite(M2,HIGH);
}

void left (char a,char b)
{
  analogWrite (E1,a);
  digitalWrite(M1,HIGH);
  analogWrite (E2,b);
  digitalWrite(M2,LOW);
}

void right (char a,char b)
{
  analogWrite (E1,a);
  digitalWrite(M1,LOW);
  analogWrite (E2,b);
  digitalWrite(M2,HIGH);
}
&#91;/javascript&#93;

<h3>Mein Code (Projekt 2)</h3>
[javascript]
// example 32.1 - IR receiver code repeater

// http://tronixstuff.com/tutorials > chapter 32

// based on code by Ken Shirriff - http://arcfn.com

int E1 = 6; //M1 Speed Control
int E2 = 5; //M2 Speed Control
int M1 = 8; //M1 Direction Control
int M2 = 7; //M2 Direction Control

int irReader = 3;    // the analog input pin for the ir reader
int irVal = 0;       // stores value from Ir reader

void setup()
{
  int i;
  for(i=5;i<=8;i++)
  pinMode(i, OUTPUT);  
  Serial.begin(9600); // for serial monitor output
}

void loop()

{
  int leftspeed = 255; //255 is maximum speed
  int rightspeed = 255;    
  irVal = analogRead(irReader);    // read the value from the ir sensor
  Serial.println(irVal);       // sends ir val to computer  

  if (irVal>210) // have we received an IR signal?
  {
        left (leftspeed,rightspeed);
        delay(500);
  }
  else
  {
        forward (leftspeed,rightspeed);
  }
}

void stop(void) //Stop
{
digitalWrite(E1,LOW);
digitalWrite(E2,LOW);
}
void forward(char a,char b)
{
analogWrite (E1,a);
digitalWrite(M1,LOW);
analogWrite (E2,b);
digitalWrite(M2,LOW);
}
void reverse (char a,char b)
{
analogWrite (E1,a);
digitalWrite(M1,HIGH);
analogWrite (E2,b);
digitalWrite(M2,HIGH);
}
void left (char a,char b)
{
analogWrite (E1,a);
digitalWrite(M1,HIGH);
analogWrite (E2,b);
digitalWrite(M2,LOW);
}
void right (char a,char b)
{
analogWrite (E1,a);
digitalWrite(M1,LOW);
analogWrite (E2,b);
digitalWrite(M2,HIGH);
}

Arduino Uno Lichterkette mit Dämmerungssensor

Aufgabenstellung

Für die Ansteuerung externer Elektronikgeräte wird eine programmierbare Lösung gesucht, die auch kabellos per Batterie betrieben werden kann und Eingabewerte (z.B. Sensorwerte) einlesen kann.

Ansatz

Die Verwendung eines Mikrocontrollers ist notwendig. Mikrocontroller sind sehr stromsparende, programmierbare und mobile Systeme, die nur das nötigste an Anschlüssen für das Aufbauen komplexer Elektronikschaltungen besitzen.

Lösung

Auf die Empfehlung eines Elektronikfreaks habe ich mir das Arduino Uno zugelegt. Hierbei handelt es sich um ein programmierbares Board mit 1KByte Flash-Speicher und einer ATMega Prozessor.

Beurteilung

Da man auf einer sehr niedrigen Ebene mit Bauteilen arbeitet, würde sich ein Elektrotechnikgrundkurs anbieten.