Code:
/********************************************************************************
asurOS, ein Pseudo-ASURO-Betriebssystem
***************************************
********************************************************************************/
#include "asuro.h"
#include "avr/pgmspace.h"
char data1[1], data2[1], data3[1], data4[1], data5[1], data6[1], data7[1];
char count = 0;
unsigned char ledColor, ledStatus, ledBackL, ledBackR, speed = 100;
int battery, countDis = 0, countAngle = 0;
void keyboardInput(void) {
//Tastatureingabe abwarten, bis ENTER gedrueckt wird.
SerRead(data1,1,0);
if(data1[0] != 0x0d) {
SerRead(data2,1,0);
if(data2[0] != 0x0d) {
SerRead(data3,1,0);
if(data3[0] != 0x0d) {
SerRead(data4,1,0);
if(data4[0] != 0x0d) {
SerRead(data5,1,0);
if(data5[0] != 0x0d) {
SerRead(data6,1,0);
if(data6[0] != 0x0d) {
SerRead(data7,1,0);
}
}
}
}
}
}
}
//Haelt die Strings der Ausgaben im Flash, sonst wird es dem Asuro zu viel;)
//THX AN izaseba!!!
void pushFlash(const char *string){
char sign;
while((sign = pgm_read_byte(string))) {
UartPutc(sign);
string++;
}
}
//Loescht die Eingabevariablen
void clear(void) {
data1[0] = 0; data2[0] = 0; data3[0] = 0; data4[0] = 0; data5[0] = 0; data6[0] = 0; data7[0] = 0;
}
//Gibt Fehlermeldung aus, falls Befehl unbekannt ist, oder zu viele Uebertragungsfehler ankommen
void irError(void) {
pushFlash(PSTR("\r\nUnknown Command!\r\n"));
count++;
if (count >= 6) {
pushFlash(PSTR("\r\nIR connection error!\r\n\r\nCheck your IR tranceiver\r\n\r\n"));
count = 0;
}
}
//Listet alle verfuegbaren Befehle auf
void commandList(void) {
pushFlash(PSTR("\r\n\r\nAwaible commands:\r\n\r\n"));
pushFlash(PSTR("\r\ncount Starts a countdown\r\n"));
pushFlash(PSTR("\r\nhelp List of all commands\r\n"));
pushFlash(PSTR("\r\nmove Change to move mode, for drive and turn\r\n"));
pushFlash(PSTR("\r\nreset resets all settings to default\r\n"));
pushFlash(PSTR("\r\nset Change to settings mode, access to LED and speed parameters\r\n"));
pushFlash(PSTR("\r\nstatus Shows actual settings and mileage\r\n"));
}
//Aendert die LED Farben mit Rueckgabewert
void ledStatusChanger(unsigned char color, unsigned char status, unsigned char left, unsigned char right) {
StatusLED(color);
FrontLED(status);
BackLED(left, right);
ledStatus = status;
ledColor = color;
ledBackL = left;
ledBackR = right;
}
//Aendert die LED Farben im Modus SET/LED
void ledSetMode(void) {
unsigned char stat[4];
pushFlash(PSTR("\r\nType new colors\r\n"));
pushFlash(PSTR("\r\nStatus LED: 0 = OFF, 1 = green, 2 = red, 3 = yellow\r\nFront LED: 0 = OFF, 1 = ON\r\n"));
pushFlash(PSTR("Back LEDs: 0 = OFF, 1 = left 2 = right 3 = both ON\r\n"));
pushFlash(PSTR("\r\ntype all parameters at once, without *space*!\r\n\r\nASURO\\set\\led>"));
SerRead(stat,4,0);
if(stat[3] == 0x0d) {
if(stat[0] == '0') {
StatusLED(OFF);
ledColor = OFF;
}
else if(stat[0] == '1') {
StatusLED(GREEN);
ledColor = GREEN;
}
else if(stat[0] == '2') {
StatusLED(RED);
ledColor = RED;
}
else if(stat[0] == '3') {
StatusLED(YELLOW);
ledColor = YELLOW;
}
else {
irError();
ledSetMode();
}
if(stat[1] == '0') {
FrontLED(OFF);
ledStatus = OFF;
}
else if(stat[1] == '1') {
FrontLED(ON);
ledStatus = ON;
}
else {
irError();
ledSetMode();
}
if(stat[2] == '0') {
BackLED(OFF,OFF);
ledBackL = OFF;
ledBackR = OFF;
}
else if(stat[2] == '1') {
BackLED(ON,OFF);
ledBackL = ON;
ledBackR = OFF;
}
else if(stat[2] == '2') {
BackLED(OFF, ON);
ledBackL = OFF;
ledBackR = ON;
}
else if(stat[2] == '3') {
BackLED(ON,ON);
ledBackL = ON;
ledBackR = ON;
}
}
else {
irError();
ledSetMode();
}
pushFlash(PSTR("\r\nSettings changed!\r\nExiting set mode\r\n\r\n"));
}
//Aendert die Geschwindigkeit im Modus SET/SPEED
void speedSetMode(void) {
pushFlash(PSTR("\r\nCurrent speed value is "));
PrintInt(speed);
pushFlash(PSTR(".\r\nType new speed value (000 - 255)\r\nASURO\\set\\speed>"));
keyboardInput();
speed = ((data1[0] - 48) * 100) + ((data2[0] - 48) * 10) + (data3[0] - 48);
pushFlash(PSTR("\r\nSettings changed!\r\nExiting set mode\r\n\r\n"));
}
//Gibt die Farben der LEDs zurueck
void ledCheck(void) {
pushFlash(PSTR("\r\n\r\bLED status:\r\n"));
if(ledColor == YELLOW) {
pushFlash(PSTR("Status LED is yellow\r\n"));
}
else if(ledColor == OFF) {
pushFlash(PSTR("Status LED is off\r\n"));
}
else if(ledColor == GREEN) {
pushFlash(PSTR("Status LED is green\r\n"));
}
else if(ledColor == RED) {
pushFlash(PSTR("Status LED is red\r\n"));
}
if(ledStatus == ON) {
pushFlash(PSTR("Front LED is on\r\n"));
}
else {
pushFlash(PSTR("Front LED is off\r\n"));
}
if(ledBackL == ON) {
pushFlash(PSTR("Left back LED is on\r\n"));
}
else {
pushFlash(PSTR("Left back LED is off\r\n"));
}
if(ledBackR == ON) {
pushFlash(PSTR("Right back LED is on\r\n"));
}
else {
pushFlash(PSTR("Right back LED is off\r\n"));
}
}
//Gibt den Status der Batterie zurueck
void batteryCheck(void) {
battery = Battery() * 0.0055;
pushFlash(PSTR("\r\nBattery status: "));
PrintInt(battery);
pushFlash(PSTR(" Volt\r\n"));
}
//Gibt die Laufzeit zurueck
void timeCheck(void) {
pushFlash(PSTR("\r\nSystem time: "));
PrintInt(Gettime());
pushFlash(PSTR(" ms\r\n"));
}
//Gibt die aktuell gesetzte Geschwindigkeit zurueck
void speedCheck(void) {
pushFlash(PSTR("\r\nSpeed value: "));
PrintInt(speed);
pushFlash(PSTR("\r\n"));
}
//Gibt die gefahrene Strecke zurueck
void disCheck(void) {
pushFlash(PSTR("\r\nMileage: "));
PrintInt(countDis);
pushFlash(PSTR(" mm\r\nTurned: "));
PrintInt(countAngle);
pushFlash(PSTR(" degrees\r\n\r\n"));
}
//Wechselt in den SET-Modus
void setMode(void) {
pushFlash(PSTR("\r\nEntering Set mode\r\nType led to change LED colors or speed to change the speed value\r\nASURO\\set>"));
keyboardInput();
//LED farbe aendern
if(data1[0] == 'l' && data2[0] == 'e' && data3[0] == 'd' && data4[0] == 0x0d) {
ledSetMode();
}
else if(data1[0] == 's' && data2[0] == 'p'&& data3[0] == 'e' && data4[0] == 'e' && data5[0] == 'd') {
speedSetMode();
}
else {
irError();
}
}
//Wechselt in den MOVE-Modus
void moveMode(void) {
int distance = 0;
int angle = 0;
pushFlash(PSTR("\r\nEntering move mode\r\n"));
pushFlash(PSTR("\r\nType path for path mode or turn for turning mode\r\n"));
pushFlash(PSTR("ASURO\\move>"));
keyboardInput();
//Teilstueck fuer Distanz
if(data1[0] == 'p' && data2[0] == 'a' && data3[0] == 't' && data4[0] == 'h' && data5[0] == 0x0d) {
pushFlash(PSTR("\r\nEntering path mode\r\n"));
pushFlash(PSTR("Type distance in mm between 0 and 1000. Negative value to drive backward.\r\nExample: -0100 for 100mm backward\r\n"));
pushFlash(PSTR("ASURO\\move\\path>"));
keyboardInput();
if(data1[0] != 0x2d) {
distance = (((data1[0] - 48) * 1000) + ((data2[0] - 48) * 100) + ((data3[0] - 48) * 10) + (data4[0] - 48));
countDis += distance;
}
else if(data1[0] == 0x2d) {
distance = (((data2[0] - 48) * 1000) + ((data3[0] - 48) * 100) + ((data4[0] - 48) * 10) + (data5[0] - 48));
countDis += distance;
distance = -distance;
}
else {
irError();
moveMode();
}
pushFlash(PSTR("\r\n\r\nAsuro will move "));
PrintInt(distance);
pushFlash(PSTR(" mm.\r\n\r\nProceed? (Y/N)"));
clear();
SerRead(data1,1,0);
if(data1[0] == 'y') {
EncoderInit();
Go(distance,speed);
pushFlash(PSTR("\r\n"));
}
else if(data1[0] == 'n') {
if(distance >= 0) {
countDis -= distance;
}
else {
countDis += distance;
}
pushFlash(PSTR("\r\n"));
}
else {
pushFlash(PSTR("\r\n"));
irError();
moveMode();
}
}
//Teilstueck fuer Winkel
else if(data1[0] == 't' && data2[0] == 'u' && data3[0] == 'r' && data4[0] == 'n' && data5[0] == 0x0d) {
pushFlash(PSTR("\r\nEntering turning mode\r\n"));
pushFlash(PSTR("\r\nType angle in degrees between 0 and 360. Negative value to turn left.\r\nExample: -090 for left\r\n"));
pushFlash(PSTR("ASURO\\move\\turn>"));
keyboardInput();
if(data1[0] != 0x2d) {
angle = (((data1[0] - 48) * 100) + ((data2[0] - 48) * 10) + (data3[0] - 48));
countAngle += angle;
}
else if(data1[0] == 0x2d) {
angle = (((data2[0] - 48) * 100) + ((data3[0] - 48) * 10) + (data4[0] - 48));
countAngle += angle;
angle = -angle;
}
else {
irError();
moveMode();
}
pushFlash(PSTR("\r\n\r\nAsuro will turn "));
PrintInt(angle);
pushFlash(PSTR(" degrees.\r\n\r\nProceed? (Y/N)"));
clear();
SerRead(data1,1,0);
if(data1[0] == 'y') {
EncoderInit();
Turn(angle,speed);
pushFlash(PSTR("\r\n"));
}
else if(data1[0] == 'n') {
if(angle >= 0) {
countAngle -= angle;
}
else {
countAngle += angle;
}
pushFlash(PSTR("\r\n"));
}
else {
pushFlash(PSTR("\r\n"));
irError();
moveMode();
}
}
else {
irError();
moveMode();
}
}
//Setzt alle Einstellungen zurueck
void reset(void) {
pushFlash(PSTR("\r\nReset all settings? (Y/N)"));
SerRead(data1,1,0);
if(data1[0] == 'y') {
ledStatusChanger(GREEN, OFF, OFF, OFF);
speed = 100;
countDis = 0;
countAngle = 0;
pushFlash(PSTR("\r\n"));
}
else if(data1[0] == 'n') {
pushFlash(PSTR("\r\n"));
}
else {
irError();
}
}
//Zaehlt einen Countdown herunter
void countDown() {
unsigned int time = 0;
pushFlash(PSTR("\r\nType countdown duration. 1 to 65535 seconds. Example: 00008 for 8 seconds\r\nASURO\\countdown>"));
keyboardInput();
time = (((data1[0] - 48) * 10000) + ((data2[0] - 48) * 1000) + ((data3[0] - 48) * 100) + (data4[0] - 48) * 10) + (data5[0] - 48);
while(time > 0) {
pushFlash(PSTR("\r\n"));
PrintInt(time);
Msleep(1000);
time--;
}
pushFlash(PSTR("\r\n0\r\n"));
}
/*************************************************************************************************
HAUPTPROGRAMM
*************
*************************************************************************************************/
int main(void) {
Init();
ledStatusChanger(GREEN, OFF, OFF, OFF);
pushFlash(PSTR("\r\nasurOS System verion 1.0.1\r\n\r\nASURO is ready\r\nAwaiting command\r\n\r\n"));
do {
pushFlash(PSTR("ASURO>"));
keyboardInput();
//Abfrage der Befehle und Starten der entsprechenden Funktion
//Modus "move"
if(data1[0] == 'm' && data2[0] == 'o' && data3[0] == 'v' && data4[0] == 'e' && data5[0] == 0x0d) {
moveMode();
clear();
}
//Modus "help"
else if(data1[0] == 'h' && data2[0] == 'e' && data3[0] == 'l' && data4[0] == 'p' && data5[0] == 0x0d) {
commandList();
clear();
}
//Modus "status"
else if(data1[0] == 's' && data2[0] == 't' && data3[0] == 'a' && data4[0] == 't' && data5[0] == 'u' && data6[0] == 's' && data7[0] == 0x0d) {
ledCheck();
batteryCheck();
speedCheck();
timeCheck();
disCheck();
clear();
}
//Modus "set"
else if(data1[0] == 's' && data2[0] == 'e' && data3[0] == 't' && data4[0] == 0x0d) {
setMode();
clear();
}
//Modus "reset"
else if(data1[0] == 'r' && data2[0] == 'e' && data3[0] == 's' && data4[0] == 'e' && data5[0] == 't' && data6[0] == 0x0d) {
reset();
clear();
}
//Modus "Countdown"
else if(data1[0] == 'c' && data2[0] == 'o' && data3[0] == 'u' && data4[0] == 'n' && data5[0] == 't' && data6[0] == 0x0d) {
countDown();
clear();
}
//Wenn man was anderes eingibt, Fehlermeldung
else {
irError();
clear();
}
}
while(1);
return 0;
}
die bedienung ist auch ganz einfach: flasht das programm, startet in windows hyperterminal, dann startet asuro. für eine übersicht aller befehle, tippt
Lesezeichen