Naja, das ist simple Stringverarbeitung... Das hat erstmal nichts mit dem RP6 zu tun sondern ist einfach Grundlagenwissen in C#.
Guck dir mal die Methoden an, die ein String bereitstellt...
Der USART kann einen Interrupt auslösen, wenn er ein Zeichen empfangen hat:
http://www.rn-wissen.de/index.php/UA...Mit_Interrupts
http://www.tschallener.net/AVR/intr_usart.pdf
Der RP6 verwendet das offensichtlich schon in seiner Lib:
(Aus RP6uart.c)Code:/** * UART receive ISR. * Handles reception to circular buffer. */ ISR(USART_RXC_vect) { static volatile uint8_t dummy; if(((uint8_t)(write_size - read_size)) < UART_RECEIVE_BUFFER_SIZE) { uart_receive_buffer[write_pos++] = UDR; write_size++; if(write_pos > UART_RECEIVE_BUFFER_SIZE) write_pos = 0; } else { dummy = UDR; uart_status = UART_BUFFER_OVERFLOW; } }
In RP6RobotBaseLib.c wird in initRobotBase() der entsprechende Receive-Interrupt freigegeben:
UCSRB = (1 << TXEN) | (1 << RXEN) | (1 << RXCIE);
Bild hier
Atmel’s products are not intended, authorized, or warranted for use
as components in applications intended to support or sustain life!
Naja, das ist simple Stringverarbeitung... Das hat erstmal nichts mit dem RP6 zu tun sondern ist einfach Grundlagenwissen in C#.
Guck dir mal die Methoden an, die ein String bereitstellt...
@radbruch
Senden tuht er jetzt ununterbrochen (soll ja auch so sein!)
Aber er "hört" nicht auf mich... und die Servos gehen in die MAX stellung?!?
Code:void task_befehle(void) { char uart_receive_buffer[UART_RECEIVE_BUFFER_SIZE+1]; uint8_t uart_status; uint8_t read_pos = 0; uint8_t write_pos = 0; uint8_t read_size = 0; uint8_t write_size = 0; static uint8_t dummy; if(((uint8_t)(write_size - read_size)) < UART_RECEIVE_BUFFER_SIZE) { uart_receive_buffer[write_pos++] = UDR; write_size++; if(write_pos > UART_RECEIVE_BUFFER_SIZE) write_pos = 0; uart_status = UART_BUFFER_OK; } else { dummy = UDR; uart_status = UART_BUFFER_OVERFLOW; } long pos = atoi(uart_receive_buffer); if(pos < 180 && pos > 0) { servo1_position = pos; } else if(pos < 360 && pos > 180) { servo2_position = pos - 180; } else if(pos < 540 && pos > 360) { servo3_position = pos - 360; } else if(pos == -1) { I2CTWI_transmitByte(PCF, 0); } else if(pos == -2) { I2CTWI_transmitByte(PCF, 3); } }
Okay, was soll das denn mal werden? Das sieht mir irgendwie schwer kompliziert aus...
Aber du hast meinen Tipp imernoch nicht berücksichtigt. Du liest immer nur das erste Zeichen aus.
Dann stellst du sofort deinen Servo auf dieses erste Zeichen. Du musst erst warten, bis die komplette Zahl übertragen wurde.
Ja, finde ich auch!Das sieht mir irgendwie schwer kompliziert aus...
Das ist das Problem, wenn ich "while(!Eingabe());" schreibe blockiert das solange die while-schleife bis ich was vom Pc schicke!Du liest immer nur das erste Zeichen aus.
Dann stellst du sofort deinen Servo auf dieses erste Zeichen. Du musst erst warten, bis die komplette Zahl übertragen wurde.
Nur mal so als Anregung... Aus meinem eigenen Code...
Code:if(getBufferLength()) { char tmp = readChar(); if (tmp =='#') { mSleep(10); counter = 0; } text[counter] = tmp; text[counter + 1] = '\0'; counter++; } int cmd = getCommand(); if(cmd) { [..] }
Also muss man nurdahintermachen?Code:if(cmd) { [..] }
So klappt es nicht:
Code:void lesen(void) { char text[50]; int counter = 0; if(getBufferLength()) { char tmp = readChar(); if (tmp =='\n') { mSleep(10); counter = 0; } text[counter] = tmp; text[counter + 1] = '\0'; counter++; } long cmd = atoi(text); if(cmd) { if(cmd == -1) { I2CTWI_transmitByte(PCF, 0); } else if(cmd == -2) { I2CTWI_transmitByte(PCF, 3); } } }
Ganz allgemeiner Tipp (ohne den Code nachvollzogen zu haben):
Sinnvolle TEXTAUSGABEN zum debuggen in den Code reinmachen damit Du sehen kannst was wo wie passiert.
Auch die Werte ausgeben lassen mit writeInteger und writeString ...
MfG,
SlyD
Nein, du hast einen ganz wichtigen (eigentlich den WICHTIGSTEN) Teil des Codes gerade gelöscht :P
Du must nun eine Funktion getCommand() schreiben, die den übertragenen String in einen Befehl umwandelt![]()
Ich brauche doch nur die Zahl, die ich per UART schicke!
Habs so versucht, klappt nicht:
Edit:Code:char Buffer[UART_RECEIVE_BUFFER_SIZE + 1]; uint32_t Eingabe(void){ static buffer_pos = 0; if(getBufferLength()) { Buffer[buffer_pos]=readChar(); if(Buffer[buffer_pos]=='\n') { buffer_pos = 0; return 1; } else if(buffer_pos >= UART_RECEIVE_BUFFER_SIZE) { buffer_pos = 0; return 2; } buffer_pos++; } return 0; } void task_befehle(void) { Eingabe(); if(Eingabe()) { long pos = atoi(Buffer); if(pos < 180 && pos > 0) { servo1_position = pos; } else if(pos < 360 && pos > 180) { servo2_position = pos - 180; } else if(pos < 540 && pos > 360) { servo3_position = pos - 360; } else if(pos == -1) { I2CTWI_transmitByte(PCF, 0); } else if(pos == -2) { I2CTWI_transmitByte(PCF, 3); } } }
hab mir mal den wert von pos anzeigen lassen, ist wenn ich eine zahl sende, sendet er mir das zurück! Wenn ich mehrer Zahlen sende macht er nicht!
Edit2: Vielleicht mache ich es doch wie Fabian! @Fabian E. was sendes du denn von pc aus?
Geändert von AsuroPhilip (05.06.2011 um 13:31 Uhr)
Lesezeichen