ArduMower: Mäher-Interface
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.
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);
}
}
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.