Sonntag, 16. Oktober 2016

Arduino und MonsterMotorShield

Ein kleines Beispiel wie ihr mit dem Monster Motor Shield 2 Motoren ansteuern könnt:

[code]
/*
 * Das Monster Motor Shield kann mit diesem Sketch über den Seriellen Monitor gesteuert werden.
 * Einfach den Speed und die Richtung durch ein Komma getrennt eingeben.
 * Beispiel: 100,1
 * Dann drehen die Motoren mit der Geschwindigkeit 100 von 255 gegen den Uhrzeigersinn
 * Mögliche Werte:
 * Speed - 0 bis 255 (0 = Stop, 255 = volle Geschwindigkeit)
 * Richtung(Dir) - 0 bis 3 (0 = im Uhrzeigersinn, 1 = gegen den Uhrzeigersinn, 2 = Motoren drehen gegeneinander,
 * 3 = Motoren drehen umgekehrt gegeneinander)
 * Bei einem Fahrzeug mit 2 Motoren wäre das dann:
 * 0 = Vorwärts
 * 1 = Rückwärts
 * 2 = nach links drehen
 * 3 = nach rechts drehen
 *
 * VNH2SP30 pin definitions
 * inApin[2] = {7, 4};  // INA: Clockwise input
 * inBpin[2] = {8, 9}; // INB: Counter-clockwise input
 * pwmpin[2] = {5, 6}; // PWM input
 * cspin[2] = {2, 3}; // CS: Current sense ANALOG input
 * enpin[2] = {0, 1}; // EN: Status of switches output (Analog pin)
 *
 * http://arduinoinc.blogspot.de/
 */

#define CS_THRESHOLD 15   // Der max Strom der durch den Treiber auf Dauer unterstützt wird

int inApin[2] = {7, 4}; // IN-A: Im Uhrzeigersinn drehen, Motor0 and Motor1 (Check:"1.2 Hardware Monster Motor Shield").
int inBpin[2] = {8, 9}; // IN-B: Gegen den Uhrzeigersinn drehen, Motor0 and Motor1 (Check: "1.2 Hardware Monster Motor Shield").
int pwmpin[2] = {5, 6};            // PWM's input
int cspin[2] = {2, 3};              // Strom (A) Sensoren Motor 1/2

int statpin = 13;

int i=0;
int speedon = 0;
int speedaktuell = 0;
int dir = 0;
int diraktuell = 0;




void setup()                        
{
  Serial.begin(9600);
  Serial.println("Ready to start - Speed,Dir");
 
  pinMode(statpin, OUTPUT);
 
  for (int i=0; i<2; i++)
      {
        pinMode(inApin[i], OUTPUT);
        pinMode(inBpin[i], OUTPUT);
        pinMode(pwmpin[i], OUTPUT);
      }
     
  for (int i=0; i<2; i++)
      {
        digitalWrite(inApin[i], LOW);
        digitalWrite(inBpin[i], LOW);
      }
}



// **************************************************************

void loop()                         
{

  // Serielle Schnittstelle auslesen
  if (Serial.available() > 0)
  {
      // nach durch "," getrennte Werte lesen
      speedon = Serial.parseInt();
      dir = Serial.parseInt();
     
      if (Serial.read() == '\n')     // nach dem Ende der Zeile schauen
      {
        // Die Werte auf bestimmte Bereiche beschränken
        speedon = constrain(speedon, 0, 255);
        dir = constrain(dir, 0, 3);
      }
     
      Serial.println("Start");
      Serial.print("SpeedOn = ");
      Serial.println(speedon, DEC);
      Serial.print("Dir = ");
      Serial.println(dir, DEC);
  }
       
 
 
  beschleunigen(speedon, dir);
 
 
 
 
 
  // Auf neue Werte/Anweisungen warten und Überprüfen ob der motor nicht blockiert ist
 
  while(i!=0)
  {                                     
      if (Serial.available() > 0)
      {
        speedon = Serial.parseInt();
        dir = Serial.parseInt();
       
        if (Serial.read() == '\n')
        {
            speedon = constrain(speedon, 0, 255);
            dir = constrain(dir, 0, 3);
        }
       
        Serial.print("SpeedOn = ");
        Serial.println(speedon, DEC);
        Serial.print("Dir = ");
        Serial.println(dir, DEC);
      }
         
      if (dir != diraktuell) beschleunigen(1, diraktuell);
     
      if (speedaktuell != speedon) beschleunigen(speedon, dir);
     
      motorGo(dir, speedon);
     
      if (analogRead(cspin[0]) > CS_THRESHOLD)        
      {
        motorOff();
      }
     
  }
       
}
// **************************************************************



void beschleunigen(int endspeed, int dirx)
{
  // Beschleunigen des Motors auf "speedon"
  if (endspeed != 0)
  {
      if (endspeed > speedaktuell)  // Wenn die neue Geschwindigkeit größer ist, dann beschleunigen
      {
     
        Serial.println("beschleunigen");

        i = speedaktuell;
       
        while(i<endspeed)
        {
          motorGo(dirx, i);   // Den Motorspeed immer um 1/255 erhöhen     
          delay(50);                        
          i++;
                                  
          if (analogRead(cspin[0]) > CS_THRESHOLD) // Ist der Motor blockiert und der Strom wird zuhoch, abschalten.
          {
            motorOff();
          }
         
          digitalWrite(statpin, LOW);
     
        }
      }


      if (endspeed < speedaktuell)  // Wenn die neue Geschwindigkeit kleiner ist, dann entschleunigen
      {
     
        i = speedaktuell;
       
        Serial.println("entschleunigen");
       
        while(i>endspeed)
        {
          motorGo(dirx, i);   // Den Motorspeed immer um 1/255 erhöhen     
          delay(50);                        
          i--;
                                  
          if (analogRead(cspin[0]) > CS_THRESHOLD) // Ist der Motor blockiert und der Strom wird zuhoch, abschalten.
          {
            motorOff();
          }
         
          digitalWrite(statpin, LOW);
     
        }
      }
      Serial.println("Speed erreicht");
      diraktuell = dir;
      speedaktuell = endspeed;
      i=1;
  }
}



void motorOff()
{

  for (int i=0; i<2; i++)
  {
    digitalWrite(inApin[i], LOW);
    digitalWrite(inBpin[i], LOW);
  }
 
  analogWrite(pwmpin[0], 0);
  analogWrite(pwmpin[1], 0);
 
  i=0;
 
  digitalWrite(13, HIGH);
 
  Serial.println("Motor Locked");
 
  delay(1000);
}



void motorGo(uint8_t direct, uint8_t pwm)
{
    if (direct <=4)
    {
      if (direct == 0) // Go forward
      {
        digitalWrite(inBpin[0], LOW);
        digitalWrite(inBpin[1], LOW);
        digitalWrite(inApin[0], HIGH);
        digitalWrite(inApin[1], HIGH);
      }
         
      if (direct == 1)  // Go backward
      {
        digitalWrite(inApin[0], LOW);
        digitalWrite(inApin[1], LOW);
        digitalWrite(inBpin[0], HIGH);
        digitalWrite(inBpin[1], HIGH);
      }
 
      if (direct == 2)  // Go left
      {
        digitalWrite(inApin[0], LOW);
        digitalWrite(inBpin[1], LOW);
        digitalWrite(inBpin[0], HIGH);
        digitalWrite(inApin[1], HIGH);
      }
     
      if (direct == 3)  // Go right
      {
        digitalWrite(inBpin[0], LOW);
        digitalWrite(inApin[1], LOW);
        digitalWrite(inApin[0], HIGH);
        digitalWrite(inBpin[1], HIGH);
      }
       
      analogWrite(pwmpin[0], pwm);
      analogWrite(pwmpin[1], pwm);
    }
}
[/code]

Donnerstag, 29. September 2016

ARDUINO und GPS - NMEA 0183 Protokoll lesen und auswerten

In diesem kleinen Post möchte ich mein Wissen zum bau eines kleinen GPS Moduls weitergeben. Ich musste selbe etwas aufwendiger suchen, um alle Informationen zu finden, die es mir dann recht schnell ermöglicht haben den GPS Receiver "HOLUX GM-210", mit dem NMEA 0183 Protokoll,
 die für mich interessanten Daten zu entlocken.

Was für Materialien hab ich benutzt?

  • GPS Receiver HOLUX GM-210
  • LCD 1602 (Idealer Weise mit UT-LCDmenueSensor Board)Wir
  • ARDUINO Nano
Die Verdrahten des ARDUINOS mit dem GPS Receiver ist denkbar einfach, wenn man die richtigen Informationen hat. Wichtig ist es das man die TTL Datenanschlüsse (5V Signalpegel) benutzt und nicht die RS232 (12V Signalpegel) Anschlüsse.



Wir verbinden also den PIN2 vom GM-210 5V VDC mit den 5V Ausgang und den PIN4 Ground mit dem GND (Ground) am ARDUINO.
Jetzt noch den PIN3 Tx(TTL) mit einem Seriellen RxPin und den PIN5 Rx(TTL) mit dem TxPIN an dem ARDUINO.



So einfach ist die Hardware installiert.

Jetzt kommen wir zu der etwas größeren Aufgabe. Das Auslesen der Daten die uns das GPS sendet, und dann natürlich das Auswerten der Daten.
Denn wir wollen ja wissen wo wir sind, wie schnell wir sind und in welche Richtung wir uns bewegen.

Es stehen natürlich noch einige Daten mehr zu der Verfügung, aber die kann sich dann nach dem gleichen Prinzip jeder so anpassen wie er es gerne hätte.



Die Erklärung hab ich noch nicht ganz fertig, aber hier schon mal der Code:

*************************************************************


 #include <string.h>
 #include <ctype.h>

 #include <LiquidCrystal.h>
  // initialize the library with the numbers of the interface pins
  LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
 
 #include <SoftwareSerial.h>
  SoftwareSerial GPSserial(7, 6); // RX | TX

String inputString = "";         // a string to hold incoming data
boolean stringComplete = false;  // whether the string is complete



 void setup()
{

// initialize serial:
  Serial.begin(9600);
  GPSserial.begin(4800);
  // reserve 200 bytes for the inputString:
  inputString.reserve(200);

  lcd.begin(16, 2);
 
  lcd.print("GPS Modul");
  delay(2000);
 
}

 void loop()
 {
      serialEvent(); // Zeile einlesen
     
  // print the string when a newline arrives:
  if (stringComplete)
    {
      Serial.println(inputString);

      // you can also look for a substring in the middle of a string:
      // Ausgabe auf dem LCD
      if (inputString.substring(1,6) == "GPRMC")
        {
          Serial.println("Yes");
          String ausgabe = (inputString.substring(20, 29));
         
          lcd.clear();
         
          lcd.setCursor(0, 0);
          lcd.print("L:");
          lcd.setCursor(0, 1);
          lcd.print("B:");
         
          lcd.setCursor(3, 0);
          lcd.print(ausgabe);
          ausgabe = "";
          ausgabe = (inputString.substring(30, 31));
          lcd.setCursor(12, 0);
          lcd.print(ausgabe);
          ausgabe = "";
          ausgabe = (inputString.substring(32, 42));
          lcd.setCursor(3, 1);
          lcd.print(ausgabe);
          ausgabe = "";
          ausgabe = (inputString.substring(43, 44));
          lcd.setCursor(13, 1);
          lcd.print(ausgabe);
          ausgabe = "";
         
          delay(1000);
         
          int kommaS = inputString.indexOf(',', 46);
          ausgabe = (inputString.substring(45, kommaS - 1));
          float kmh = ausgabe.toFloat();
          kmh = kmh*1.852;

          lcd.clear();
         
          lcd.setCursor(0, 0);
          lcd.print("S:");
          lcd.setCursor(0, 1);
          lcd.print("W:");
 
          lcd.setCursor(3, 0);
          lcd.print(kmh, 6);
          ausgabe = "";
          int kommaW = inputString.indexOf(',', kommaS + 1);
          ausgabe = (inputString.substring(kommaS + 1, kommaW));
          lcd.setCursor(3, 1);
          lcd.print(ausgabe);
          ausgabe = "";
          delay(1000);
        }
     
      // clear the string:
      inputString = "";
      stringComplete = false;
    }
 }



 void serialEvent() {
  while (GPSserial.available())
    {
    // get the new byte:
    char inChar = (char)GPSserial.read();
   
    // add it to the inputString:
    inputString += inChar;
   
    // if the incoming character is a newline, set a flag
    // so the main loop can do something about it:
    if (inChar == '\n')
      {
        stringComplete = true;
      }
  }
}