ArduMower: Mäher-Interface: Unterschied zwischen den Versionen
(3 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 | 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 | 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. | Der aktuelle Programmcode ist nachfolgend dargestellt. | ||
Zeile 34: | Zeile 36: | ||
#include <TFTv2.h> | #include <TFTv2.h> | ||
#include <SPI.h> | #include <SPI.h> | ||
#include <Wire.h> | |||
#include "play_btn.h" | #include "play_btn.h" | ||
#include "stop_btn.h" | #include "stop_btn.h" | ||
Zeile 40: | Zeile 43: | ||
int ColorPaletteHigh = 60; | 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 | int color = WHITE; //Paint brush color | ||
unsigned int colors[4] = {GREEN, RED, BLUE, YELLOW}; | unsigned int colors[4] = {GREEN, RED, BLUE, YELLOW}; | ||
int BMPtemp = 0; | |||
// For better pressure precision, we need to know the resistance | // For better pressure precision, we need to know the resistance | ||
// between X+ and X- Use any multimeter to read it | // between X+ and X- Use any multimeter to read it | ||
Zeile 50: | Zeile 70: | ||
void setup() | void setup() | ||
{ | { | ||
Wire.begin(8); // join i2c bus with address #8 | |||
Wire.onReceive(receiveEvent); // register event | |||
Tft.TFTinit(); //init TFT library | Tft.TFTinit(); //init TFT library | ||
// Tft.setOrientation(1); | |||
Serial.begin(9600); | Serial.begin(9600); | ||
//Draw the pallet | //Draw the pallet | ||
Zeile 61: | Zeile 85: | ||
bmpdraw(right_btn, 2*60+16, 320-44); | bmpdraw(right_btn, 2*60+16, 320-44); | ||
bmpdraw(left_btn, 3*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); | |||
} | } | ||
Zeile 87: | Zeile 116: | ||
{ | { | ||
Tft.fillCircle(p.x,p.y,4,color); | Tft.fillCircle(p.x,p.y,4,color); | ||
} | } | ||
Zeile 100: | Zeile 127: | ||
unsigned char data[5000] = {0}; | unsigned char data[5000] = {0}; | ||
int index = 0; | int index = 0; | ||
Zeile 112: | Zeile 140: | ||
{ | { | ||
data[j * 4 + (7 - k) + i * 32] = bitRead( temp_btn, 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) | if (data[j * 4 + (7 - k) + i * 32] == 1) | ||
{ | { | ||
Zeile 125: | Zeile 154: | ||
} | } | ||
} | } | ||
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> | </source> | ||
</big> | </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 | 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.