ArduMower: Mäher-Interface: Unterschied zwischen den Versionen
Keine Bearbeitungszusammenfassung |
|||
(16 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 | ||
=Aktueller Entwicklungsstand = | =Aktueller Entwicklungsstand = | ||
Die Einbindung des | Das Mäher-Interface wird mit einem Touch-Display realisiert. Der Hersteller stellt in einem [http://wiki.seeed.cc/2.8inch_TFT_Touch_Shield_v2.0/ 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. | |||
[[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 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. | |||
<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 == | |||
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.
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.