ArduMower: Mäher-Interface: Unterschied zwischen den Versionen

Aus HSHL Mechatronik
Zur Navigation springen Zur Suche springen
Keine Bearbeitungszusammenfassung
 
(6 dazwischenliegende Versionen desselben Benutzers werden nicht angezeigt)
Zeile 12: Zeile 12:


== Erwartungen an die Projektlösung ==
== Erwartungen an die Projektlösung ==
* Zeigt die wichtigsten Werte des Ardumower an
* Ermöglicht einfache Bedienung des Ardumower
* Ermöglicht einfache Bedienung des Ardumower


Zeile 20: Zeile 21:
[[Datei:Display_Mower.png|500px|center|Display des Ardumower-Interface]]
[[Datei:Display_Mower.png|500px|center|Display des Ardumower-Interface]]


Wie in der Abbildung zu sehen, wurden bereits vier Buttons in die Bedienoberfläche eingepflegt, deren Funktionalität zum nächsten Meilenstein umgesetzt werden soll.
Wie in der Abbildung zu sehen, wurden bereits vier Buttons in die Bedienoberfläche eingepflegt, deren Funktionalität zum noch umgesetzt werden muss.
Für die Wetterbeständige Montage wird zunächst ein Provisorium in Form eines Zip-Beutels verwendet, um das Display vor Wettereinflüssen zu schützen aber auch eine schnelle Entnahme zu ermöglichen.
Für die Montage wird eine Aussparung in die Deckplatte des Ardumower eingefräst. Um das Display vor Wettereinflüssen zu schützen sollte allerdings noch eine Schutzvorrichtung entwickeltwerden.


[[Datei:HMI Code Seite1.png|500px|center|Display des Ardumower-Interface]]
Der aktuelle Programmcode ist nachfolgend dargestellt.


<big>
<source lang="cpp">
#define TRIGGER 3
#define ECHO 2 
// Paint application - Demonstate both TFT and Touch Screen
#include <stdint.h>
#include <SeeedTouchScreen.h>
#include <TFTv2.h>
#include <SPI.h>
#include <Wire.h>
#include "play_btn.h"
#include "stop_btn.h"
#include "left_btn.h"
#include "right_btn.h"
int ColorPaletteHigh = 60;
int OutputI2C = 0;
int Bumper = 0;
int Ultraschall_r = 0;
int Ultraschall_m = 0;
int Ultraschall_l = 0;
int Perimeter = 0;
int compx = 0;
int compy = 0;
int compz = 0;
int accx = 0;
int accy = 0;
int accz = 0;
int gyrox = 0;
int gyroy = 0;
int gyroz = 0;
int color = WHITE;  //Paint brush color
unsigned int colors[4] = {GREEN, RED, BLUE, YELLOW};
int BMPtemp = 0;
// For better pressure precision, we need to know the resistance
// between X+ and X- Use any multimeter to read it
// The 2.8" TFT Touch shield has 300 ohms across the X plate
TouchScreen ts = TouchScreen(XP, YP, XM, YM); //init TouchScreen port pins
void setup()
{
  Wire.begin(8);                // join i2c bus with address #8
  Wire.onReceive(receiveEvent); // register event
  Tft.TFTinit();  //init TFT library
// Tft.setOrientation(1);
  Serial.begin(9600);
  //Draw the pallet
  for (int i = 0; i < 4; i++)
  {
    Tft.fillRectangle(i * 60, 320 - 60, 60, ColorPaletteHigh, WHITE);
      }
    bmpdraw(play_btn, 0*60+16, 320-44);
    bmpdraw(stop_btn, 1*60+16, 320-44);
    bmpdraw(right_btn, 2*60+16, 320-44);
    bmpdraw(left_btn, 3*60+16, 320-44);
  Tft.drawString("Bumper: ", 0, 0, 2, WHITE);
  Tft.drawNumber(BMPtemp, 150, 0, 2, WHITE);
  Tft.drawString("US__links: ", 0, 18, 2, WHITE);
  Tft.drawString("US__mitte: ", 0, 36, 2, WHITE);
  Tft.drawString("US_rechts: ", 0, 54, 2, WHITE);
  Tft.drawString("Perimeter: ", 0, 72, 2, WHITE);
}
void loop()
{
 
  // a point object holds x y and z coordinates.
  Point p = ts.getPoint();
  //map the ADC value read to into pixel co-ordinates
  p.x = map(p.x, TS_MINX, TS_MAXX, 0, 240);
  p.y = map(p.y, TS_MINY, TS_MAXY, 0, 320);
  // we have some minimum pressure we consider 'valid'
  // pressure of 0 means no pressing!
  if (p.z > __PRESURE) {
    // Detect  paint brush color change
    if (p.y > 320 - ColorPaletteHigh)
    {
      color = colors[p.x / ColorPaletteHigh];
    }
    else
    {
      Tft.fillCircle(p.x,p.y,4,color);
    }
  }
}
void bmpdraw(const unsigned char f[], int x, int y)
{
  uint32_t time = millis();
unsigned char data[5000] = {0};
  int index = 0;
  for ( int i = 0; i < 32; i++)
  {
    for (int j = 0; j < 4; j++)
    {
      //int j = 4;
      unsigned char temp_btn = f[j + i * 4];
      for (int k = 7; k >= 0; k--)
      {
        data[j * 4 + (7 - k) + i * 32] = bitRead( temp_btn, k );
        //Serial.print(data[j * 8 + (7 - k) + i * 64]);
        if (data[j * 4 + (7 - k) + i * 32] == 1)
        {
        Tft.setPixel(x + i, y + ((7 - k)+j*4), WHITE);
        }
        else
      {
        Tft.setPixel(x + i, y + ((7 - k)+j*4), BLACK);
      }
      }
    }
  }
 
  void receiveEvent(int howMany) {
  while (1 < Wire.available()) { // loop through all but the last
    byte bID = Wire.read(); // receive byte
    byte b1 = Wire.read(); // receive byte
    byte b2 = Wire.read(); // receive byte
    byte b3 = Wire.read(); // receive byte
    byte b4 = Wire.read(); // receive byte
    byte b5 = Wire.read(); // receive byte
 
  OutputI2C = bID;
  Bumper = b1;
  switch(bID)
  {
  case 1: Bumper = b1;
  break;
  case 2: {
            Ultraschall_r = b1;
            Ultraschall_m = b2;
            Ultraschall_l = b3;
          }
  break;
  case 3: {
            compx = b1;
            compy = b2;
            compz = b3;
          }
  break;
  case 4: {
            accx = b1;
            accy = b2;
            accz = b3;
          }
  break;
  case 5: {
            gyrox = b1;
            gyroy = b2;
            gyroz = b3;
          }
  break;
  }
  }
    String OutputI2C_St = "Zaehler:" +OutputI2C;
    String Bumper_St = "Bumper"+Bumper;
    String test =OutputI2C_St;
    char *test2;
    Serial.println(test2);
  if (BMPtemp != Bumper)
  {
  Tft.drawNumber(BMPtemp, 150, 0, 2, BLACK);
  BMPtemp = Bumper;
  Tft.drawNumber(BMPtemp, 150, 0, 2, WHITE);
  }
}
void drawString(String string,INT16U poX, INT16U poY, INT16U size,INT16U fgcolor)
{
      int i = 0;
      int lang = string.length();
      char temp = 0;
      char *draw = 0;
      for ( i;i<lang;i++)
      {
        temp = string.charAt(i);
        *draw = &temp;
        Tft.drawChar(draw, poX, poY, size, fgcolor);
      }
}
</source>
</big>
== I2C Kommunikation ==
Für die Anzeige von den aktuellen Daten des Ardumower müssen diese über I2C vom Arduino Mega im Ardumower zum Arduino Uno am Display gesendet werden. Da die Datenübertragung nur bitweise funktioniert, müssen die Datensätze im Ardumower aufgespalten werden. Dazu wird ein ID Bit gesendet, mit welchem der Datenatz identifiziert werden kann und anschließend werden alle notwendigen Bits gesendet, um die Daten vollständig abzubilden.
==Bewertung des Fortschritts ==
==Bewertung des Fortschritts ==
Der Gesamtfortschritt für das Mäher-Interface zum Meilenstein 3 beläuft sich auf 60 %, da durch die Programmierung, die für Meilenstein 4 vorgesehen ist noch ein großer zeitlicher Aufwand für das Interface bevorsteht. Die zu Meilenstein 3 gesteckten Ziele der I2C- Anbindung an die Hauptplatine, der Inbetriebnahme und der Montage sind zu 85 % abgeschlossen. Es fehlen eine softwareseitige Einbindung der I2C Kommunikation und die Montage ist für ein einfacheres Handling bei der Programmierung zunächst provisorisch vorgenommen worden.
Der Gesamtfortschritt für das Mäher-Interface zum Meilenstein 4 beläuft sich auf 85 %, da die Programmierung, die für Meilenstein 4 vorgesehen war nicht vollständig abgeschlossen werden konnte. Es fehlen unter anderem Datensätze bei der I2C Kommunikation und die Bedienung konnte nicht volständig umgesetzt werden. Die Montage ist abgeschlossen aber ein Schutz vor Nässe kann ergänzt werden.

Aktuelle Version vom 13. Februar 2018, 17:07 Uhr

Dieser Wiki-Beitrag ist Teil eines Projektes, welches im Rahmen vom Projekt Ardumower im 6. Semester Mechatronik absolviert wurde. Ziel des Beitrags ist es, eine nachhaltige Dokumentation zu schaffen, welche die Ergebnisse festhält und das weitere Arbeiten am Projekt ermöglicht.

Autoren: Simon Kohfeld

Betreuer: Prof. Dr.-Ing. Schneider, Prof. Dr.-Ing. Mirek Göbel


Aufgabe

Einbindung einer Bedienschnittstelle für den ArduMower


Erwartungen an die Projektlösung

  • Zeigt die wichtigsten Werte des Ardumower an
  • Ermöglicht einfache Bedienung des Ardumower

Aktueller Entwicklungsstand

Das Mäher-Interface wird mit einem Touch-Display realisiert. Der Hersteller stellt in einem Wiki-Artikel die Bibliotheken und eine Bedienungsanleitung zur Verfügung, wodurch eine schnelle Inbetriebnahme ermöglicht wird. Die Anbindung an die Hauptplatine erfolgt über I2C. Das Display ist Pin kompatibel mit einem Arduino Uno, welcher für Visualisierungsaufgaben und die Eingabeverarbeitung genutzt werden kann. Die I2C Pins sind nicht mit dem UNO verbunden, wodurch eine optimale Einbindung in das Gesamtsystem möglich ist durch die Herstellung eines passenden Kabels. Das Display ist in der Abbildung dargestellt.

Display des Ardumower-Interface
Display des Ardumower-Interface

Wie in der Abbildung zu sehen, wurden bereits vier Buttons in die Bedienoberfläche eingepflegt, deren Funktionalität zum noch umgesetzt werden muss. Für die Montage wird eine Aussparung in die Deckplatte des Ardumower eingefräst. Um das Display vor Wettereinflüssen zu schützen sollte allerdings noch eine Schutzvorrichtung entwickeltwerden.

Der aktuelle Programmcode ist nachfolgend dargestellt.

#define TRIGGER 3 
#define ECHO 2  

// Paint application - Demonstate both TFT and Touch Screen
#include <stdint.h>
#include <SeeedTouchScreen.h>
#include <TFTv2.h>
#include <SPI.h>
#include <Wire.h>
#include "play_btn.h"
#include "stop_btn.h"
#include "left_btn.h"
#include "right_btn.h"

int ColorPaletteHigh = 60;
int OutputI2C = 0;
int Bumper = 0;
int Ultraschall_r = 0;
int Ultraschall_m = 0;
int Ultraschall_l = 0;
int Perimeter = 0;
int compx = 0;
int compy = 0;
int compz = 0;
int accx = 0;
int accy = 0;
int accz = 0;
int gyrox = 0;
int gyroy = 0;
int gyroz = 0;
int color = WHITE;  //Paint brush color
unsigned int colors[4] = {GREEN, RED, BLUE, YELLOW};

int BMPtemp = 0;
// For better pressure precision, we need to know the resistance
// between X+ and X- Use any multimeter to read it
// The 2.8" TFT Touch shield has 300 ohms across the X plate

TouchScreen ts = TouchScreen(XP, YP, XM, YM); //init TouchScreen port pins

void setup()
{
  Wire.begin(8);                // join i2c bus with address #8
  Wire.onReceive(receiveEvent); // register event

  Tft.TFTinit();  //init TFT library
 // Tft.setOrientation(1);
  Serial.begin(9600);
  //Draw the pallet
  for (int i = 0; i < 4; i++)
  {
    Tft.fillRectangle(i * 60, 320 - 60, 60, ColorPaletteHigh, WHITE);
      }
    bmpdraw(play_btn, 0*60+16, 320-44);
    bmpdraw(stop_btn, 1*60+16, 320-44);
    bmpdraw(right_btn, 2*60+16, 320-44);
    bmpdraw(left_btn, 3*60+16, 320-44);
  Tft.drawString("Bumper: ", 0, 0, 2, WHITE);
  Tft.drawNumber(BMPtemp, 150, 0, 2, WHITE);
  Tft.drawString("US__links: ", 0, 18, 2, WHITE);
  Tft.drawString("US__mitte: ", 0, 36, 2, WHITE);
  Tft.drawString("US_rechts: ", 0, 54, 2, WHITE);
  Tft.drawString("Perimeter: ", 0, 72, 2, WHITE);
}

void loop()
{
  
  // a point object holds x y and z coordinates.
  Point p = ts.getPoint();

  //map the ADC value read to into pixel co-ordinates

  p.x = map(p.x, TS_MINX, TS_MAXX, 0, 240);
  p.y = map(p.y, TS_MINY, TS_MAXY, 0, 320);

  // we have some minimum pressure we consider 'valid'
  // pressure of 0 means no pressing!

  if (p.z > __PRESURE) {
    // Detect  paint brush color change
    if (p.y > 320 - ColorPaletteHigh)
    {
      color = colors[p.x / ColorPaletteHigh];
    }
    else
    {
      Tft.fillCircle(p.x,p.y,4,color);
    }

  }
}

void bmpdraw(const unsigned char f[], int x, int y)
{
  uint32_t time = millis();

unsigned char data[5000] = {0};
  int index = 0;
 


  for ( int i = 0; i < 32; i++)
  {
    for (int j = 0; j < 4; j++)
    {
      //int j = 4;
      unsigned char temp_btn = f[j + i * 4];

      for (int k = 7; k >= 0; k--)
      {
        data[j * 4 + (7 - k) + i * 32] = bitRead( temp_btn, k );
        //Serial.print(data[j * 8 + (7 - k) + i * 64]);
        if (data[j * 4 + (7 - k) + i * 32] == 1)
        {
        Tft.setPixel(x + i, y + ((7 - k)+j*4), WHITE);
        }

        else
       {
        Tft.setPixel(x + i, y + ((7 - k)+j*4), BLACK);
       }
      }

    }
  }
  
  void receiveEvent(int howMany) {
  while (1 < Wire.available()) { // loop through all but the last
    byte bID = Wire.read(); // receive byte
    byte b1 = Wire.read(); // receive byte
    byte b2 = Wire.read(); // receive byte
    byte b3 = Wire.read(); // receive byte
    byte b4 = Wire.read(); // receive byte
    byte b5 = Wire.read(); // receive byte
  
  OutputI2C = bID;
  Bumper = b1;
  switch(bID)
  {
  case 1: Bumper = b1;
  break;
  case 2: {
            Ultraschall_r = b1;
            Ultraschall_m = b2;
            Ultraschall_l = b3;
          }
  break;
  case 3: {
            compx = b1;
            compy = b2;
            compz = b3;
          }
  break;
  case 4: {
            accx = b1;
            accy = b2;
            accz = b3;
          }
  break;
  case 5: {
            gyrox = b1;
            gyroy = b2;
            gyroz = b3;
          }
  break;
  }
  }
    String OutputI2C_St = "Zaehler:" +OutputI2C;
    String Bumper_St = "Bumper"+Bumper;

    String test =OutputI2C_St;
    char *test2;

    Serial.println(test2);

   if (BMPtemp != Bumper)
   {
   Tft.drawNumber(BMPtemp, 150, 0, 2, BLACK);
   BMPtemp = Bumper;
   Tft.drawNumber(BMPtemp, 150, 0, 2, WHITE);
   }

}
void drawString(String string,INT16U poX, INT16U poY, INT16U size,INT16U fgcolor)
{
      int i = 0;
      int lang = string.length();
      char temp = 0;
      char *draw = 0;
      for ( i;i<lang;i++)
      {
        temp = string.charAt(i);
        *draw = &temp;
        Tft.drawChar(draw, poX, poY, size, fgcolor);
      }
}

I2C Kommunikation

Für die Anzeige von den aktuellen Daten des Ardumower müssen diese über I2C vom Arduino Mega im Ardumower zum Arduino Uno am Display gesendet werden. Da die Datenübertragung nur bitweise funktioniert, müssen die Datensätze im Ardumower aufgespalten werden. Dazu wird ein ID Bit gesendet, mit welchem der Datenatz identifiziert werden kann und anschließend werden alle notwendigen Bits gesendet, um die Daten vollständig abzubilden.

Bewertung des Fortschritts

Der Gesamtfortschritt für das Mäher-Interface zum Meilenstein 4 beläuft sich auf 85 %, da die Programmierung, die für Meilenstein 4 vorgesehen war nicht vollständig abgeschlossen werden konnte. Es fehlen unter anderem Datensätze bei der I2C Kommunikation und die Bedienung konnte nicht volständig umgesetzt werden. Die Montage ist abgeschlossen aber ein Schutz vor Nässe kann ergänzt werden.