Loading...
Pages: [1] 2   Go Down
Author Topic: Ardu-Megatank, ein Roboterkettenfahrzeug Projektvorstellung (In Progress)  (Read 5283 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Edison Member
*
Karma: 17
Posts: 1928
Wo ein Wille ist, da ist auch ein Weg !
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Willkommen zum Ardu-Megatank Projekt !


Von hier aus gelangen Sie direkt zu den einzelnen Kapiteln des Projektes:

Die Basis des Roboters:
http://arduino.cc/forum/index.php/topic,61753.msg447054.html#msg447054

Die Beleuchtung:
http://arduino.cc/forum/index.php/topic,61753.msg477168.html#msg477168

Die zentrale Steuerung, KI-Zentrum:
http://arduino.cc/forum/index.php/topic,61753.msg726943.html#msg726943

Die Lagesensorik:
http://arduino.cc/forum/index.php/topic,61753.msg741159.html#msg741159

Die Umgebungssensoren:
http://arduino.cc/forum/index.php/topic,61753.msg747087.html#msg747087

Die Fernsteuerung:
http://arduino.cc/forum/index.php/topic,61753.msg821076.html#msg821076

Der Motortreiber: (Aktualisiert am 18.7.2012)
http://arduino.cc/forum/index.php/topic,61753.msg829022.html#msg829022

Die Programmierung des Motortreibers:
http://arduino.cc/forum/index.php/topic,61753.msg829043.html#msg829043

Die Geschwindigkeitsanzeige:
http://arduino.cc/forum/index.php/topic,61753.msg833118.html#msg833118

Die Stromversorgung, unterer Panzerbereich:
http://arduino.cc/forum/index.php/topic,61753.msg833242.html#msg833242

Die Stromversorgung, oberer Panzerbereich: (Aktualisiert am 18.7.2012)
http://arduino.cc/forum/index.php/topic,61753.msg833246.html#msg833246

Die Sprachausgabe:
http://arduino.cc/forum/index.php/topic,61753.msg833247.html#msg833247

Die Uhr, RTC DS1307:
http://arduino.cc/forum/index.php/topic,61753.msg837673.html#msg837673

Die I2C Kommunikation:
http://arduino.cc/forum/index.php/topic,61753.msg837718.html#msg837718

Der Temperatursensor:
http://arduino.cc/forum/index.php/topic,61753.msg838904.html#msg838904

Die Programmierung der KI:
http://arduino.cc/forum/index.php/topic,61753.msg841416.html#msg841416

Die KI:
http://arduino.cc/forum/index.php/topic,61753.msg842510.html#msg842510

Der Roboterarm:
http://arduino.cc/forum/index.php/topic,61753.msg842809.html#msg842809

Zukünftige Features:
http://arduino.cc/forum/index.php/topic,61753.msg844812.html#msg844812
« Last Edit: July 18, 2012, 07:35:49 am by Megaionstorm » Logged

Mein Arduino Projekte Blog:
http://ardu-megatank.blogspot.de/

Germany
Offline Offline
Newbie
*
Karma: 0
Posts: 43
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Hallo, das hört sich wirklich interessant an!
Mit was für einer Fernbedienung steuerst du ihn?
Einer R/C Fernbedienung? iPhone?

Viele Grüße
Florian
Logged

0
Offline Offline
Edison Member
*
Karma: 17
Posts: 1928
Wo ein Wille ist, da ist auch ein Weg !
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Die Basis des Roboters


http://www.graupner.de/de/products/90037/product.aspx

Dieses RC Panzermodel im Maßstab 1:16 dient als Basis für den Bau eines Roboters.
Autonom agierend, aber auch durch eine Fernsteuerung (2,4GHz) steuerbar.

Das autonome agieren gilt nicht nur für die Steuerung des Panzers selber, durch die KI, sondern auch für die des Roboterarms.
« Last Edit: June 24, 2012, 05:44:38 pm by Megaionstorm » Logged

Mein Arduino Projekte Blog:
http://ardu-megatank.blogspot.de/

0
Offline Offline
Edison Member
*
Karma: 17
Posts: 1928
Wo ein Wille ist, da ist auch ein Weg !
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Die Beleuchtung

Die Beleuchtung besteht aus 2 Scheinwerfern (5mm Leds), Bremslicht (5mm Leds), Blinker (5mm Leds) und orange Signallichter (3mm und 5mm Leds).



Dies ist die Lichtsteuerung, ein Atmega328 und ein TLC5940NT.
Gesteuert wird die Lichtsteuerung durch den Sanguino über I2C.

Die Notwendigkeit für den Einschalten der Scheinwerfer wird durch die Umgebungshelligkeitmessung eines
LDR bestimmt.

Die LED's und dehren Kabel wurden mit Heisskleber befestigt.
« Last Edit: June 29, 2012, 12:45:22 am by Megaionstorm » Logged

Mein Arduino Projekte Blog:
http://ardu-megatank.blogspot.de/

0
Offline Offline
Edison Member
*
Karma: 17
Posts: 1928
Wo ein Wille ist, da ist auch ein Weg !
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Der Sketch für die Beleuchtung, noch nicht ganz fertig !
Code:
// Ardu-Megatank I2C Beleuchtungssteuerung

#include "Tlc5940.h"
#include <Wire.h>

#define TRUE 1
#define FALSE 0

byte ScheinwerferAn;
byte BlinkenLinks;
byte BlinkenRechts;
byte BlinkLedAn;
byte BremsLichtAn;
byte BatterieLow;
unsigned long BlinkTimer1;
unsigned long BlinkTimer2;

char* PatternFrame[] = { "0000000000000000",
                         "5555555555555555",
                         "cccccccccccccccc",
                         "ffffffffffffffff",
                         "ff0000ff00000000",
                         "ffffffff00000000",
                       };
char* Frame;
int Light1[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
int Light2[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};

void setup()
{
   Tlc.init();
   Tlc.clear();
   Tlc.update();
   ScheinwerferAn = FALSE;
   BlinkenLinks = FALSE;
   BlinkenRechts = FALSE;
   BlinkTimer1 = 0;
   BlinkTimer2 = 0;
   BlinkLedAn = FALSE;
   BremsLichtAn = FALSE;
   BatterieLow = TRUE;
}

void loop()
{
  if (ScheinwerferAn == TRUE)
  {
    Tlc.set(0, 4095);
    Tlc.set(1, 4095);
  }
    else
    {
      Tlc.set(0, 0);
      Tlc.set(1, 0);
    }
  if (BlinkenLinks == TRUE)
  {
    BlinkTimer2 = millis();
    if(BlinkTimer2 - BlinkTimer1 > 250)
    {
      BlinkTimer1 = BlinkTimer2;  
      if (BlinkLedAn == FALSE)
      {
        BlinkLedAn = TRUE;
        Tlc.set(2, 4095);
        Tlc.set(3, 4095);
      }
        else
        {
          BlinkLedAn = FALSE;
          Tlc.set(2, 0);
          Tlc.set(3, 0);
        }
    }
  }
    
  if (BlinkenRechts == TRUE)
  {
    BlinkTimer2 = millis();
    if(BlinkTimer2 - BlinkTimer1 > 250)
    {
      BlinkTimer1 = BlinkTimer2;  
      if (BlinkLedAn == FALSE)
      {
        BlinkLedAn = TRUE;
        Tlc.set(4, 4095);
        Tlc.set(5, 4095);
      }
        else
        {
          BlinkLedAn = FALSE;
          Tlc.set(4, 0);
          Tlc.set(5, 0);
        }
    }
  }

  if (BremsLichtAn == TRUE)
  {
    Tlc.set(6, 4095);
    Tlc.set(7, 4095);
  }
    else
    {
      Tlc.set(6, 0);
      Tlc.set(7, 0);
    }
    
  if (BatterieLow == TRUE)
  {
    Flash(Light1);
  }
  Tlc.update();
}

void Flash(int LightOld[16])
{
  byte PatternNr;
  BlinkLedAn = FALSE;
  BlinkTimer1 = millis();
  Flash_SetPattern(LightOld, PatternFrame[4]);
  while (1) // Endlosschleife !!!
  {
     for (PatternNr = 0; PatternNr <= 3; PatternNr++)
     {
        Flash_PatternFading(LightOld, PatternFrame[PatternNr], 3);
        BlinkTimer2 = millis();
        if(BlinkTimer2 - BlinkTimer1 > 250)
        {
           BlinkTimer1 = BlinkTimer2;  
           if (BlinkLedAn == FALSE)
           {
              BlinkLedAn = TRUE;
              Flash_SetPattern(LightOld, PatternFrame[5]);  
           }
             else
             {
                BlinkLedAn = FALSE;
                Flash_SetPattern(LightOld, PatternFrame[4]);  
             }
        }
    }
    delay(150);
  }
}

void Flash_SetPattern(int LightOld[16], char* LightNew)
{
  int Helligkeit[16];
  for (int LightNr = 0; LightNr <= 15; LightNr += 1)
  {
    Helligkeit[LightNr] = byte(char(LightNew[LightNr])) -48;
    if (Helligkeit[LightNr] > 9) Helligkeit[LightNr] -= 39;
    if (Helligkeit[LightNr] > 0) Helligkeit[LightNr] = (Helligkeit[LightNr] + 1) * 256;
    if (Helligkeit[LightNr] > 0) Helligkeit[LightNr] -= 1;
  }
  for (int Channel = 0; Channel <= 15; Channel += 1)
  {
    Tlc.set(Channel, Helligkeit[Channel]);
    Light1[Channel] = Helligkeit[Channel];
  }
  Tlc.update();
}

void DeclareParam(int Param1, int Param2, int Param3, int Param4, int Param5, int Param6, int Param7, int Param8, int Param9, int Param10, int Param11, int Param12, int Param13, int Param14, int Param15, int Param16)
{
  Light2[0] = Param1;
  Light2[1] = Param2;
  Light2[2] = Param3;
  Light2[3] = Param4;
  Light2[4] = Param5;
  Light2[5] = Param6;
  Light2[6] = Param7;
  Light2[7] = Param8;
  Light2[8] = Param9;
  Light2[9] = Param10;
  Light2[10] = Param11;
  Light2[11] = Param12;
  Light2[12] = Param13;
  Light2[13] = Param14;
  Light2[14] = Param15;
  Light2[15] = Param16;
}

void ParamFading(int LightOld[16], int LightNew[16], int Geschw)
{
  float Fade[16];
  int Helligkeit[16];
  for (int LightNr = 0; LightNr <= 15; LightNr += 1)
  {
    Helligkeit[LightNr] = LightNew[LightNr];
    if (Helligkeit[LightNr] < 0) Helligkeit[LightNr] = 0;
    if (Helligkeit[LightNr] > 4095) Helligkeit[LightNr] = 4095;
    Fade[LightNr] = (Helligkeit[LightNr] - LightOld[LightNr])/100;
  }
  for (int Anzahl = 1; Anzahl <= 100; Anzahl += 1)
  {
    for (int Channel = 0; Channel <= 15; Channel += 1)
    {
       Tlc.set(Channel, LightOld[Channel] + (Anzahl * Fade[Channel]));
    }
    Tlc.update();
    delay(Geschw);
  }
  for (int Channel = 0; Channel <= 15; Channel += 1)
  {
    Tlc.set(Channel, Helligkeit[Channel]);
    Light1[Channel] = Helligkeit[Channel];
  }
  Tlc.update();
}

void SetParam(int LightOld[16], int LightNew[16])
{
  float Fade[16];
  int Helligkeit[16];
  for (int LightNr = 0; LightNr <= 15; LightNr += 1)
  {
    Helligkeit[LightNr] = LightNew[LightNr];
    if (Helligkeit[LightNr] < 0) Helligkeit[LightNr] = 0;
    if (Helligkeit[LightNr] > 4095) Helligkeit[LightNr] = 4095;
  }
  for (int Channel = 0; Channel <= 15; Channel += 1)
  {
    Tlc.set(Channel, Helligkeit[Channel]);
    Light1[Channel] = Helligkeit[Channel];
  }
  Tlc.update();
}

void PatternFading(int LightOld[16], char* LightNew, int Geschw)
{
  float Fade[16];
  int Helligkeit[16];
  for (int LightNr = 0; LightNr <= 15; LightNr += 1)
  {
    Helligkeit[LightNr] = byte(char(LightNew[LightNr])) -48;
    if (Helligkeit[LightNr] > 9) Helligkeit[LightNr] -= 39;
    if (Helligkeit[LightNr] > 0) Helligkeit[LightNr] = (Helligkeit[LightNr] + 1) * 256;
    if (Helligkeit[LightNr] > 0) Helligkeit[LightNr] -= 1;
    Fade[LightNr] = (Helligkeit[LightNr] - LightOld[LightNr])/100;
  }
  for (int Anzahl = 1; Anzahl <= 100; Anzahl += 1)
  {
    for (int Channel = 0; Channel <= 15; Channel += 1)
    {
       Tlc.set(Channel, LightOld[Channel] + (Anzahl * Fade[Channel]));
    }
    Tlc.update();
    delay(Geschw);
  }
  for (int Channel = 0; Channel <= 15; Channel += 1)
  {
    Tlc.set(Channel, Helligkeit[Channel]);
    Light1[Channel] = Helligkeit[Channel];
  }
  Tlc.update();
}

void Flash_PatternFading(int LightOld[16], char* LightNew, int Geschw)
{
  float Fade[16];
  int Helligkeit[16];
  for (int LightNr = 8; LightNr <= 15; LightNr += 1)
  {
    Helligkeit[LightNr] = byte(char(LightNew[LightNr])) -48;
    if (Helligkeit[LightNr] > 9) Helligkeit[LightNr] -= 39;
    if (Helligkeit[LightNr] > 0) Helligkeit[LightNr] = (Helligkeit[LightNr] + 1) * 256;
    if (Helligkeit[LightNr] > 0) Helligkeit[LightNr] -= 1;
    Fade[LightNr] = (Helligkeit[LightNr] - LightOld[LightNr])/100;
  }
  for (int Anzahl = 1; Anzahl <= 100; Anzahl += 1)
  {
    for (int Channel = 8; Channel <= 15; Channel += 1)
    {
       Tlc.set(Channel, LightOld[Channel] + (Anzahl * Fade[Channel]));
    }
    Tlc.update();
    delay(Geschw);
  }
  for (int Channel = 8; Channel <= 15; Channel += 1)
  {
    Tlc.set(Channel, Helligkeit[Channel]);
    Light1[Channel] = Helligkeit[Channel];
  }
  Tlc.update();
}

void SetPattern(int LightOld[16], char* LightNew)
{
  int Helligkeit[16];
  for (int LightNr = 0; LightNr <= 15; LightNr += 1)
  {
    Helligkeit[LightNr] = byte(char(LightNew[LightNr])) -48;
    if (Helligkeit[LightNr] > 9) Helligkeit[LightNr] -= 39;
    if (Helligkeit[LightNr] > 0) Helligkeit[LightNr] = (Helligkeit[LightNr] + 1) * 256;
    if (Helligkeit[LightNr] > 0) Helligkeit[LightNr] -= 1;
  }
  for (int Channel = 0; Channel <= 15; Channel += 1)
  {
    Tlc.set(Channel, Helligkeit[Channel]);
    Light1[Channel] = Helligkeit[Channel];
  }
  Tlc.update();
}

void Drehen(int LightOld[16], int Anzahl, byte Richtung, int Geschw)
{
  int Hilfs;
  for (int Schritt = 0; Schritt <= Anzahl; Schritt += 1)
  {
     for (int Channel = 0; Channel <= 15; Channel += 1)
     {
        Tlc.set(Channel, LightOld[Channel]);
     }
     Tlc.update();
     delay(Geschw);
     if (Schritt < Anzahl)
     {
       for (int Channel = 15; Channel >= 1; Channel -= 1)
       {
         if (Richtung > 0)
         {
            Hilfs = LightOld[Channel];
            LightOld[Channel] = LightOld[Channel - 1];
            LightOld[Channel - 1] = Hilfs;
         }
            else
            {
               Hilfs = LightOld[15 - Channel];
               LightOld[15 - Channel] = LightOld[15 - (Channel - 1)];
               LightOld[15 - (Channel - 1)] = Hilfs;              
            }
       }
     }
  }
  for (int Channel = 0; Channel <= 15; Channel += 1)
  {
    Light1[Channel] = LightOld[Channel];
  }
}
« Last Edit: June 29, 2012, 12:48:02 am by Megaionstorm » Logged

Mein Arduino Projekte Blog:
http://ardu-megatank.blogspot.de/

Germany
Offline Offline
Full Member
***
Karma: 1
Posts: 158
... has much to learn
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Sehr schön, gefällt mir echt super.

Was kann der Arm gewichtsmäßig tragen/bewegen?
Logged


0
Offline Offline
Edison Member
*
Karma: 17
Posts: 1928
Wo ein Wille ist, da ist auch ein Weg !
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hallo flomei,

der Roboterarm befindet sich noch in der Erprobungsphase.
Werde noch drei der Servos gegen stärkere mit 17kg/cm Torque austauschen und den Arm dann auf das doppelte verlängern !

Zur Zeit schafft er eine Zig-Packung voller Sand !
Logged

Mein Arduino Projekte Blog:
http://ardu-megatank.blogspot.de/

0
Offline Offline
Edison Member
*
Karma: 17
Posts: 1928
Wo ein Wille ist, da ist auch ein Weg !
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Die zentrale Steuerung, KI-Zentrum

Das Gehirn des Roboters bildet ein Sanguino mit einem Atmega644.
Der jederzeit durch einen Atmega1284 mit doppelter Speicherkapazität ersetzt werden kann.



Als Bootloader wird der BT Arduino Bootloader verwendet:
http://code.google.com/p/brewtroller/downloads/detail?name=BTArduino-0020-Win.zip&can=2&q=label%3AOpSys-Windows

Bei der Stromversorgung werden zwei L4940V5 und ein LF33CV verwendet.
Beide 'VERY LOW DROP' Spannungsregler.

Die blaue Platine ist ein Voltage Sensor zur Überwachung der Akkuspannung.
Im Batteriefach in der Mitte des Panzers befinden sich 8 Mignon-Akkus, welche durch die Akkuladebuchse innerhalb des Fahrzeuges geladen werden können.
Diese ist in der linken Seite des Fotos zu sehen.

Auf der Unterseite des Panzers, vorne und hinten, befindet sich je ein nach unten gerichteter GP2Y0D810Z0F Infrarotsensor. Diese dienen als FALL AVOIDING SENSORS.
« Last Edit: June 20, 2012, 09:23:41 am by Megaionstorm » Logged

Mein Arduino Projekte Blog:
http://ardu-megatank.blogspot.de/

0
Offline Offline
Edison Member
*
Karma: 17
Posts: 1928
Wo ein Wille ist, da ist auch ein Weg !
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Die Lagesensorik

Der Test eines ADXL345:

Damit der Roboter später auch weis wie schräg er in der Landschaft herumsteht !

http://imageshack.us/clip/my-videos/441/crr.mp4/

In dem Video leuchtet immer die LED welche in die Richtung zeigt in der das Breadboard nach unten geneigt wird.

Code:
#include <Wire.h>

#define DEVICE (0x53)    //ADXL345 device address
#define TO_READ (6)        //num of bytes we are going to read each time (two bytes for each axis)

byte buff[TO_READ] ;    //6 bytes buffer for saving data read from the device
char str[512];                      //string buffer to transform data before sending it to the serial port

void setup()
{
  Wire.begin();        // join i2c bus (address optional for master)
  Serial.begin(9600);  // start serial for output

  //Turning on the ADXL345
  writeTo(DEVICE, 0x2D, 0);      
  writeTo(DEVICE, 0x2D, 16);
  writeTo(DEVICE, 0x2D, 8);
  pinMode(10, OUTPUT);
  pinMode(11, OUTPUT);
  pinMode(12, OUTPUT);
  pinMode(13, OUTPUT);
  digitalWrite(10, LOW);
  digitalWrite(11, LOW);
  digitalWrite(12, LOW);
  digitalWrite(13, LOW);
}

void loop()
{
  int regAddress = 0x32;    //first axis-acceleration-data register on the ADXL345
  int x, y, z;

  readFrom(DEVICE, regAddress, TO_READ, buff); //read the acceleration data from the ADXL345

  //each axis reading comes in 10 bit resolution, ie 2 bytes.  Least Significat Byte first!!
  //thus we are converting both bytes in to one int
  x = (((int)buff[1]) << 8) | buff[0];  
  y = (((int)buff[3])<< 8) | buff[2];
  z = (((int)buff[5]) << 8) | buff[4];

  //we send the x y z values as a string to the serial port
  sprintf(str, "%d %d %d", x, y, z);  
  Serial.print(str);
  Serial.print(10, BYTE);
  if(y>= 6)
    {digitalWrite(11, HIGH);}
    else {digitalWrite(11, LOW);}
  if(x<= 2)
    {digitalWrite(12, HIGH);}
    else {digitalWrite(12, LOW);}
  if(x>= 14)
    {digitalWrite(10, HIGH);}
    else {digitalWrite(10, LOW);}    
  if(y<= -6)
    {digitalWrite(13, HIGH);}
    else {digitalWrite(13, LOW);}
  //It appears that delay is needed in order not to clog the port
  delay(50);
}

//---------------- Functions
//Writes val to address register on device
void writeTo(int device, byte address, byte val) {
  Wire.beginTransmission(device); //start transmission to device
  Wire.send(address);        // send register address
  Wire.send(val);        // send value to write
  Wire.endTransmission(); //end transmission
}

//reads num bytes starting from address register on device in to buff array
void readFrom(int device, byte address, int num, byte buff[]) {
  Wire.beginTransmission(device); //start transmission to device
  Wire.send(address);        //sends address to read from
  Wire.endTransmission(); //end transmission

    Wire.beginTransmission(device); //start transmission to device
  Wire.requestFrom(device, num);    // request 6 bytes from device

  int i = 0;
  while(Wire.available())    //device may send less than requested (abnormal)
  {
    buff[i] = Wire.receive(); // receive a byte
    i++;
  }
  Wire.endTransmission(); //end transmission
}

Der HMC5883L der zusammen mit dem ADXL345 notwendig ist um ein
'Tilt kompensierendes Kompassmodul' zu bauen ist in die Testschaltung noch nicht integriert !
Dann kann auch die Himmelsrichtung ermittelt werden.
https://www.loveelectronics.co.uk/Tutorials/13/tilt-compensated-compass-arduino-tutorial
« Last Edit: June 24, 2012, 03:50:56 pm by Megaionstorm » Logged

Mein Arduino Projekte Blog:
http://ardu-megatank.blogspot.de/

0
Offline Offline
Edison Member
*
Karma: 17
Posts: 1928
Wo ein Wille ist, da ist auch ein Weg !
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Die Umgebungssensoren

PIR, Ultraschall- und Infrarotsensoren zur Entfernungsmessung.
Ein LDR zur Umgebungshelligkeitsmessung für die Scheinwerfersteuerung.

Mit diesen Sensoren tastet der Roboter seine Umgebung ab.

Benutzt werden 2 Ultraschallsensoren für die Vorwärtsfahrt und ein Infrarotsensor für die Rückwärtsfahrt.

2 Infrarotsensoren sind unterhalb des Panzer angebracht, sie dienen als FALL AVOIDING Sensoren.
Durch diese kann der Panzer sogar auf einer Tischplatte fahren ohne das die Gefahr des herunterfallens an der Tischkante besteht.

Auf jeder Seite des Panzers werden 3 Infrarotsensoren benutzt.

Ein PIR Sensor dient im GUARD-Modus des Panzers zur Bewegungswahrnehmung von Lebewesen.
« Last Edit: June 24, 2012, 06:42:21 pm by Megaionstorm » Logged

Mein Arduino Projekte Blog:
http://ardu-megatank.blogspot.de/

0
Offline Offline
Edison Member
*
Karma: 17
Posts: 1928
Wo ein Wille ist, da ist auch ein Weg !
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Die Fernsteuerung

Die Hardware ist fertig aufgebaut und muss nur noch zur Datenübertragung per Funk programmiert werden !



Sie besteht aus einem Spannungsregler LF33CV, Arduino Pro Mini Enhanced 3,3V 16Mhz, Voltage Sensor, nRF24L01 Funk, 9V Block Batterie, 1 orange LED, 1 Bicolor LED Rot/Grün und 2 Joysticks.

In der Version 2 bekommt die Fernbedienung noch ein 1,8" TFT-Display, ohne Touchscreen, zum Anzeigen der Telemetriedaten welche vom Panzer zur Fernsteuerung übertragen werden !




Wenn z.B. die Akkuspannung im Panzer zu niedrig ist soll in der Fernbedienung die orange Led zu blinken beginnen.
Das Displaymodul besitzt aber auch einen SD-CARD Reader mit dem die Telemetriedaten auf SD-Card gespeichert werden können.

Als nächstes wird in dem Batteriefach in dem sich zur Zeit eine 9V Blockbatterie befindet eine Halterung für zwei AA Micro Batterien eingebaut.

Desweiteren wird der Spannungsregler der zur Zeit in der Fernsteuerung eingebaut ist durch zwei NCP1400-3,3V Step-Up Breakout Boards ersetzt werden.
http://www.watterott.com/de/NCP1400-33V-Step-Up-Breakout

Code:
// 1、Voltage Sensor Vcc: 0V - 16.5V
// 2、Voltage Sensor detection range: 0.01611328125V - 16.5V
// Voltage Sensor Out an Arduino analog Pin 1
//
// Joystick -> Arduino
// GND      -> GND
// Vcc      -> 3,3V
// VRx1     -> analog Pin 1
// VRy1     -> analog Pin 2
// VRx2     -> analog Pin 3
// VRy2     -> analog Pin 4

#define VoltageSensorPin     A0
#define Joystick1XPin        A1
#define Joystick1YPin        A2
#define Joystick2XPin        A3
#define Joystick2YPin        A4
#define AkkuStatusLed1Pin     9
#define AkkuStatusLed2Pin    10
#define TankAkkuStatusLedPin  6
#define KeypadMPOutPin1       5
#define KeypadMPOutPin2       4
#define KeypadMPOutPin3       3
#define KeypadMPInPin1       A5
#define KeypadMPInPin2       A6

#include <Wire.h>

int JoystickValue;
int VoltageSensorRead;
double VoltageSensorValue;
byte Keypressed1;
byte Keypressed2;
byte Keypressed3;
byte Keypressed4;
byte Hoch1;
byte Runter1;
byte Links1;
byte Rechts1;
byte Hoch2;
byte Runter2;
byte Links2;
byte Rechts2;


void setup()
{
  pinMode(VoltageSensorPin, INPUT);
  pinMode(Joystick1XPin, INPUT);
  pinMode(Joystick1YPin, INPUT);
  pinMode(Joystick2XPin, INPUT);
  pinMode(Joystick2YPin, INPUT);
  pinMode(AkkuStatusLed1Pin, OUTPUT);
  pinMode(AkkuStatusLed2Pin, OUTPUT);
  pinMode(TankAkkuStatusLedPin, OUTPUT);
  pinMode(KeypadMPOutPin1, OUTPUT);
  pinMode(KeypadMPOutPin2, OUTPUT);
  pinMode(KeypadMPOutPin3, OUTPUT);
  pinMode(KeypadMPInPin1, INPUT);
  pinMode(KeypadMPInPin2, INPUT);
  digitalWrite(AkkuStatusLed1Pin, LOW);
  digitalWrite(AkkuStatusLed2Pin, LOW);
  digitalWrite(TankAkkuStatusLedPin, LOW);
  digitalWrite(KeypadMPOutPin1, LOW);
  digitalWrite(KeypadMPOutPin2, LOW);
  digitalWrite(KeypadMPOutPin3, LOW);
  Hoch1 = 0;
  Runter1 = 0;
  Links1 = 0;
  Rechts1 = 0;
  Hoch2 = 0;
  Runter2 = 0;
  Links2 = 0;
  Rechts2 = 0;
  Serial.begin(19200);
}

void loop()
{
  VoltageSensorRead = analogRead(VoltageSensorPin);
  VoltageSensorValue = 0.01611328125 * (VoltageSensorRead); // 0.0244140625 = 16.5V / 1024
  if (VoltageSensorValue > 6.0)
  {
     digitalWrite(AkkuStatusLed1Pin, HIGH); // LED Grün
     digitalWrite(AkkuStatusLed2Pin, LOW);
  }
    else if ((VoltageSensorValue <= 6.0) and (VoltageSensorValue > 4.5))
    {
       digitalWrite(AkkuStatusLed1Pin, HIGH); // LED
       digitalWrite(AkkuStatusLed2Pin, HIGH); // Orange
    }
      else if (VoltageSensorValue <= 4.5)
      {
         digitalWrite(AkkuStatusLed1Pin, LOW);
         digitalWrite(AkkuStatusLed2Pin, HIGH); // LED Rot
      }
  digitalWrite(TankAkkuStatusLedPin, HIGH); // Für Akkuladezustand Telemetriedaten vom Panzer
  
    digitalWrite(KeypadMPOutPin1, HIGH);
  if (analogRead(KeypadMPInPin2) > 0)
  {
     Keypressed3 = 1;
  }
    else
    {
       Keypressed3 = 0;  
    }
  digitalWrite(KeypadMPOutPin1, LOW);
  digitalWrite(KeypadMPOutPin2, HIGH);
  if (analogRead(KeypadMPInPin2) > 0)
  {
     Keypressed4 = 1;
  }
    else
    {
       Keypressed4 = 0;  
    }
  digitalWrite(KeypadMPOutPin2, LOW);
  digitalWrite(KeypadMPOutPin3, HIGH);
  if (analogRead(KeypadMPInPin2) > 0)
  {
     Keypressed1 = 1;
  }
    else
    {
       Keypressed1 = 0;  
    }
  if (analogRead(KeypadMPInPin1) > 0)
  {
     Keypressed2 = 1;
  }
    else
    {
       Keypressed2 = 0;  
    }
  digitalWrite(KeypadMPOutPin3, LOW);
  JoystickValue = analogRead(Joystick1XPin);
  if ((JoystickValue > 507) and (JoystickValue < 513))
  {
     Hoch1 = 0;
     Runter1 = 0;
  }
    else if (JoystickValue < 508)
    {
       Runter1 = map(JoystickValue, 507, 0, 150, 1);  
    }
      else
      {
         Hoch1 = map(JoystickValue, 513, 1023, 150, 1);
      }

  JoystickValue = analogRead(Joystick1YPin);
  if ((JoystickValue > 496) and (JoystickValue < 502))
  {
     Links1 = 0;
     Rechts1 = 0;
  }
    else if (JoystickValue < 497)
    {
       Links1 = map(JoystickValue, 496, 0, 150, 1);  
    }
      else
      {
         Rechts1 = map(JoystickValue, 502, 1023, 150, 1);
      }

  JoystickValue = analogRead(Joystick2XPin);
  if ((JoystickValue > 513) and (JoystickValue < 519))
  {
     Hoch2 = 0;
     Runter2 = 0;
  }
    else if (JoystickValue < 514)
    {
       Hoch2 = map(JoystickValue, 513, 0, 150, 1);  
    }
      else
      {
         Runter2 = map(JoystickValue, 519, 1023, 150, 1);
      }

  JoystickValue = analogRead(Joystick2YPin);
  if ((JoystickValue > 518) and (JoystickValue < 524))
  {
     Links2 = 0;
     Rechts2 = 0;
  }
    else if (JoystickValue < 519)
    {
       Rechts2 = map(JoystickValue, 518, 0, 150, 1);  
    }
      else
      {
         Links2 = map(JoystickValue, 524, 1023, 150, 1);
      }

  
  Serial.print("Transmitter Akku Voltage: ");
  Serial.print(VoltageSensorValue);
  Serial.println("V");
  Serial.print("  Hoch = ");
  Serial.println(Hoch1, DEC);
  Serial.print(" Links = ");
  Serial.print(Links1, DEC);
  Serial.print(" Rechts = ");
  Serial.println(Rechts1, DEC);
  Serial.print("Runter = ");
  Serial.println(Runter1, DEC);
  Serial.println();
  Serial.print("  Hoch = ");
  Serial.println(Hoch2, DEC);
  Serial.print(" Links = ");
  Serial.print(Links2, DEC);
  Serial.print(" Rechts = ");
  Serial.println(Rechts2, DEC);
  Serial.print("Runter = ");
  Serial.println(Runter2, DEC);
  Serial.println();
  Serial.print("Key 1: ");
  Serial.print(Keypressed1, DEC);
  Serial.print("  Key 2: ");
  Serial.print(Keypressed2, DEC);
  Serial.print("  Key 3: ");
  Serial.print(Keypressed3, DEC);
  Serial.print("  Key 4: ");
  Serial.println(Keypressed4, DEC);
  Serial.println();
  delay(200);
}
Die Funkübertragung selber ist im Sketch noch nicht implementiert !

Dazu gehört unter anderem die BINDING Funktion zwischen Sender und Empfänger und das FREQUENZHOPPING unter Benutzung von 50 Frequenzen, 2,4GHz - 2,5GHz.
« Last Edit: June 23, 2012, 02:36:04 pm by Megaionstorm » Logged

Mein Arduino Projekte Blog:
http://ardu-megatank.blogspot.de/

0
Offline Offline
Edison Member
*
Karma: 17
Posts: 1928
Wo ein Wille ist, da ist auch ein Weg !
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Der Motortreiber

Die Basis der beiden Motortreiber ist der TLE5206:



Bei der blauen Farbe der Spannungsregler handelt es sich um 'Teslanol Schutz- und Isolationslack'.

Die Schaltung ist so ausgelegt das der TLE mehr Amper liefern kann als der Motor benötigt und der Spannungsregler kann mehr Amper liefern als der TLE benötigt !

Zu jedem Motortreiber gehört ein ACS712 Current Sensor, 20A Version, der zwischen Motor und Motortreiber geschaltet wird.

Da die Motortreiber für das Innenleben des Panzers zu gross sind werden diese ausserhalb des Panzers befestigt !
Zum Schutz vor der Umwelt befinden sich die Motortreiber jedoch jeder in einem separaten Gehäuse, aus diesem Grund werden Sie um eine aktive Kühlung erweitert.
Ein Atmega8 wird durch einen DS18B20 die Temperatur messen und gegebenenfalls zwei 5V Lüfter einschalten.
Einer an der Front des Motortreibergehäuses und einen am Deckel.
Der vordere saugt frische Luft ins Gehäuse und der obere drückt die Luft aus dem Gehäuse.




Alle Streifenrasterplatinen die in diesem Projekt benutzt werden sind reine Prototypen und werden später durch prof. gefertigte Platinen ersetzt ! Leiterplatenservice !

In den zwei grossen Gehäusen sind die Motortreiber eingebaut:
« Last Edit: July 18, 2012, 07:32:56 am by Megaionstorm » Logged

Mein Arduino Projekte Blog:
http://ardu-megatank.blogspot.de/

0
Offline Offline
Edison Member
*
Karma: 17
Posts: 1928
Wo ein Wille ist, da ist auch ein Weg !
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Die Programmierung des Motortreibers

Ein TLE5206 Motortreiber Sketch ohne Geschwindigkeitssteuerung:
Code:
// Motorsteuerung ohne Geschwindigkeitsregelung !
void setup()
{
  pinMode(5, OUTPUT);  // Linker Kettenantrieb (Motortreiber 1 - IN1)
  pinMode(6, OUTPUT);  // (Motortreiber 1 - IN2)
  pinMode(10, OUTPUT); // Rechter Kettenantrieb (Motortreiber 2 - IN1)
  pinMode(11, OUTPUT); // (Motortreiber 2 - IN2)
  digitalWrite(5, LOW);
  digitalWrite(6, LOW);
  digitalWrite(10, LOW);
  digitalWrite(11, LOW);
}

void loop()
{
  digitalWrite(5, LOW);   // Vorwärts
  digitalWrite(6, HIGH);
  digitalWrite(10, LOW);  // Vörwärts
  digitalWrite(11, HIGH);
  delay(10000);
  digitalWrite(5, LOW);  // Stop
  digitalWrite(6, LOW);
  digitalWrite(10, LOW); // Stop
  digitalWrite(11, LOW);
  delay(2000);
  digitalWrite(5, HIGH);  // Rückwärts
  digitalWrite(6, LOW);
  digitalWrite(10, HIGH); // Rückwärts
  digitalWrite(11, LOW);
  delay(10000);
  digitalWrite(5, LOW);  // Stop
  digitalWrite(6, LOW);
  digitalWrite(10, LOW); // Stop
  digitalWrite(11, LOW);
  delay(2000);
}
Ohne Geschwindigkeitssteuerung müssen die Arduino Pins welche mit IN1 und IN2 der Motortreiber verbunden werden nicht PWM fähig sein !
Die Motoren drehen sich hierbei immer mit der Höchstgeschwindigkeit !


Ein TLE5206 Motortreiber Sketch mit Geschwindigkeitsregelung:
Code:
// Motorsteuerung mit Geschwindigkeitsregelung !!!
// 255 = Stllstand, 1 = Höchstgeschwindigkeit
// 150 ist der Mindestwert, da die Motoren des Panzers sonst nicht anlaufen !!!

#define Motortreiber1_IN1_Pin 5  // PWM
#define Motortreiber1_IN2_Pin 6  // PWM
#define Motortreiber2_IN1_Pin 10 // PWM
#define Motortreiber2_IN2_Pin 11 // PWM

byte Speed;

void setup()
{
  pinMode(Motortreiber1_IN1_Pin, OUTPUT);  // Linker Kettenantrieb (Motortreiber 1 - IN1)
  pinMode(Motortreiber1_IN2_Pin, OUTPUT);  // (Motortreiber 1 - IN2)
  pinMode(Motortreiber2_IN1_Pin, OUTPUT); // Rechter Kettenantrieb (Motortreiber 2 - IN1)
  pinMode(Motortreiber2_IN2_Pin, OUTPUT); // (Motortreiber 2 - IN2)
  digitalWrite(Motortreiber1_IN1_Pin, LOW);
  digitalWrite(Motortreiber1_IN2_Pin, LOW);
  digitalWrite(Motortreiber2_IN1_Pin, LOW);
  digitalWrite(Motortreiber2_IN2_Pin, LOW);
}

void loop()
{  
  for (Speed = 150; Speed >= 1; Speed--) // Muss mindestens 1 sein, sonst läuft Motor nicht mehr an !!!
  {
    analogWrite(Motortreiber1_IN1_Pin, Speed);
    digitalWrite(Motortreiber1_IN2_Pin, HIGH);  // Linker Kettenantrieb vorwärts
    analogWrite(Motortreiber2_IN1_Pin, Speed);
    digitalWrite(Motortreiber2_IN2_Pin, HIGH); // Rechter Kettenantrieb vorwärts
    delay(200);
  }
  delay(1000);
  analogWrite(Motortreiber1_IN1_Pin, 255);   // Linker Kettenantrieb stop
  digitalWrite(Motortreiber1_IN2_Pin, HIGH);
  analogWrite(Motortreiber2_IN1_Pin, 255);  // Rechter Kettenantrieb stop
  digitalWrite(Motortreiber2_IN2_Pin, HIGH);
  delay(2000);
  
  for (Speed = 150; Speed >= 1; Speed--) // Muss mindestens 1 sein, sonst läuft Motor nicht mehr an !!!
  {
    digitalWrite(Motortreiber1_IN1_Pin, HIGH);
    analogWrite(Motortreiber1_IN2_Pin, Speed);  // Linker Kettenantrieb rückwärts
    digitalWrite(Motortreiber2_IN1_Pin, HIGH);
    analogWrite(Motortreiber2_IN2_Pin, Speed); // Rechter Kettenantrieb rückwärts
    delay(200);
  }
  delay(1000);
  digitalWrite(Motortreiber1_IN1_Pin, HIGH);
  analogWrite(Motortreiber1_IN2_Pin, 255);    // Linker Kettenantrieb stop
  digitalWrite(Motortreiber2_IN1_Pin, HIGH);
  analogWrite(Motortreiber2_IN2_Pin, 255);   // Rechter Kettenantrieb stop
  delay(2000);
}
Bei der Benutzung der Geschwindigkeitssteuerung müssen die Arduino Pins welche mit IN1 und IN2 der Motortreiber verbunden werden auf jeden Fall alle PWM fähig sein !
Es ist vom Minimum bis zum Maximum eine stufenlose Geschwindigkeitsregelung möglich !


Ein Video des ersten Test der beiden Motortreiber:
http://www.youtube.com/watch?v=Jo0RRn883P8&feature=youtu.be
« Last Edit: June 20, 2012, 09:15:47 am by Megaionstorm » Logged

Mein Arduino Projekte Blog:
http://ardu-megatank.blogspot.de/

0
Offline Offline
Edison Member
*
Karma: 17
Posts: 1928
Wo ein Wille ist, da ist auch ein Weg !
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Die Geschwindigkeitsanzeige

Einer der Motortreiber mit aufmontierter Ledbar für die Anzeige der vorwärts und rückwarts Fahrgeschwindigkeit.
3 X Rot, 7 X Grün.
Rot für rückwärts und grün für vorwärts.





Es werden in der Schaltung zwei 74HC595 für die Ledbarsteuerung benutzt.

Code:
// Bargraphledmodul -> Arduino
// Pin 1 -> digital Pin 6
// Pin 2 -> digital Pin 8
// Pin 3 -> digital Pin 7

#define _74HC595_DataPin  6 // Ledbar Modul Pin 1
#define _74HC595_LatchPin 8 // Ledbar Modul Pin 2
#define _74HC595_ClockPin 7 // Ledbar Modul Pin 3

byte _74HC595_LedBarpin[10] = {5, 6, 7, 9, 10, 11, 12, 13, 14, 15};

void setup() {
  pinMode(_74HC595_LatchPin, OUTPUT);
  pinMode(_74HC595_DataPin, OUTPUT); 
  pinMode(_74HC595_ClockPin, OUTPUT);
}

void loop() {
  for (int thisLed = 0; thisLed <= 9; thisLed++)
  {
    registerWrite(_74HC595_LedBarpin[thisLed], HIGH); // write data to the shift registers:
    delay(150);
    // if this is not the first LED, turn off the previous LED:
    if (thisLed > 0) {
      registerWrite(_74HC595_LedBarpin[thisLed - 1], LOW);
    }
    // if this is  the first LED, turn off the highest LED:
    else {
      registerWrite(15, LOW);
    }
    // pause between LEDs:
    delay(10);
  }
}

void registerWrite(int whichPin, int whichState) // This method sends bits to the shift registers:
{
  unsigned int bitsToSend = 0; // the bits you want to send. Use an unsigned int, so you can use all 16 bits
  digitalWrite(_74HC595_LatchPin, LOW); // turn off the output so the pins don't light up while you're shifting bits
  bitWrite(bitsToSend, whichPin, whichState); // turn on the next highest bit in bitsToSend
  byte registerOne = highByte(bitsToSend); // break the bits into two bytes, one for the first register and one for the second
  byte registerTwo = lowByte(bitsToSend);
  shiftOut(_74HC595_DataPin, _74HC595_ClockPin, MSBFIRST, registerOne); // shift the bytes out
  shiftOut(_74HC595_DataPin, _74HC595_ClockPin, MSBFIRST, registerTwo);
  digitalWrite(_74HC595_LatchPin, HIGH); // turn on the output so the LEDs can light up
}
« Last Edit: June 22, 2012, 04:15:09 pm by Megaionstorm » Logged

Mein Arduino Projekte Blog:
http://ardu-megatank.blogspot.de/

0
Offline Offline
Edison Member
*
Karma: 17
Posts: 1928
Wo ein Wille ist, da ist auch ein Weg !
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Die Stromversorgung, unterer Panzerbereich

Stromversorgung der Logik, Sensoren und LED-Beleuchtung.


Die Spannung der Akkus wird während des Betriebes durch einen Voltage Sensor überwacht.

8 Mignon-Akkus mit je 2700mAh, welche über eine Ladebuchse innerhalb des Panzers geladen werden können.

Hierzu wird ein 8 Zellen Ladegerät aus dem RC-Bereich benutzt.
Ansmann Powerjack 8 Delta:
« Last Edit: June 24, 2012, 09:36:44 am by Megaionstorm » Logged

Mein Arduino Projekte Blog:
http://ardu-megatank.blogspot.de/

Pages: [1] 2   Go Up
Print
 
Jump to: