Gerät via RS232 ansteuern Im Unterforum Microcontroller - Beschreibung: Hardware - Software - Ideen - Projekte
Autor |
Gerät via RS232 ansteuern |
|
|
|
|
BID = 755635
MechMac666 Gesprächig
Beiträge: 197 Wohnort: Salzkotten
|
|
Hallo,
ich habe hier eine Kamera, welche ich mittels µc (AVR-GCC) fernsteuern möchte.
Die Steuerbefehle wie auch die Antworten vom Gerät sind mir bekannt.
Allerdings gibt es da ein Problem. Die Kommunikation läuft über Hex-Zahlen ab.
Ich habe Sende- und Empfangsroutinen, welche mit char arbeiten.
Die Senderoutine durchläuft eine Schleife in der jeder Char byteweise gesendet wird.
Diese Sub-Routuine erwartet als Eingabeformat uint8_t.
Jetzt frage ich mich, kann man einen HEX-Wert irgendwie in uint8_t umwandeln damit ich es senden kann?
Oder anders gefragt:
Kann ich das
1B 53 06 00 00 11 02 00 00 00 13 00
hiermit
void USART_putc(uint8_t byte)
{
while(bit_is_clear(UCSR0A,UDRE0)); //warten auf Datenregister empty
UDR0=byte;
}
senden?
Gruß
|
|
BID = 755641
DonComi Inventar
Beiträge: 8605 Wohnort: Amerika
|
|
Hallo,
Nochmal genauer: sind das ASCII-Werte oder redest du von binären Werten in Hexadezimalschreibweise?
uint8_t ist die per ISO-Standard (afaik 99) festgelegte Bezeichnung für eine acht Bit lange Ganzzahl ohne Vorzeichen. Sie entspricht damit genau unsigned char.
Wird char nur als Datentyp für ein Zeichen benutzt (weswegen er auch so heißt), dann ist sogar das Vorzeichen egal, uint8_t, int8_t, signed char und unsigned char eignen sich also alle für einfache Zeichen.
Nur bei Arithmetik kann es fies werden, wenn das MSB falsch interpretiert wird (Vorzeichenbit).
Edit:
Typischerweise gibt man Bytes so an, wie du es oben gemacht hast, also in Hexadezimalrepräsentation, also zur Basis 16.
In C kann man eine Zahl als Hexadezimalzahl angeben, indem man ein 0x davorsetzt.
1B 53 06 00 00 11 02 00 00 00 13 00
-->
USART_putc(0x1b);
USART_putc(0x53);
USART_putc(0x06);
USART_putc(0x00);
USART_putc(0x00);
USART_putc(0x11);
USART_putc(0x02);
USART_putc(0x00);
USART_putc(0x00);
USART_putc(0x00);
USART_putc(0x13);
USART_putc(0x00);
Das macht man so meist nicht, sondern legt solche Muster im ROM ab:
static prog_char command[] = {0x1B, 0x53, 0x06, 0x00, 0x00, 0x11, 0x02, 0x00, 0x00, 0x00, 0x13, 0x00};
void uart_putcdata(prog_char* data, uint8_t len)
{
while(len--)
{
USART_putc(pgm_read_byte(data));
data++;
}
}
uart_putcdata(command, sizeof command);
Will die Kamera hingegen die Bytes in ASCII-Werten, dann kannst du das einfach als String senden.
_________________
[ Diese Nachricht wurde geändert von: DonComi am 20 Mär 2011 22:34 ] |
|
BID = 755646
MechMac666 Gesprächig
Beiträge: 197 Wohnort: Salzkotten
|
Hallo,
nein keine ASCII-Werte. Rechts die Darstellung als String zeigt das es wohl Zahlen zind.
1B 53 06 00 00 11 02 00 00 00 13 00 .S..........
Ich vermute mal das man es ganz simpel sendet wie folgt:
USART_putc(0x1B);
USART_putc(0x53);
USART_putc(0x06);
.
.
.
Gruß
|
BID = 755648
clembra Inventar
Beiträge: 5404 Wohnort: Weeze / Niederrhein
|
So wären es binäre Werte, keine Hexadezimalen Zahlen. Für die müsste es so aussehen:
USART_putc('1'); // = 0x31
USART_putc('B'); // = 0x42 (kleines b = 0x62)
USART_putc('5'); // = 0x35
USART_putc('3'); // = 0x33
USART_putc('0'); // = 0x30
USART_putc('6'); // = 0x36
Da jetzt die Beispielzeile aber vollständig ist (.S......) steht fest, dass dein Beispiel-Code korrekt ist - auch wenn dieser meiner Meinung nach nicht mit der Beschreibung in deinem ersten Posting übereinstimmt
_________________
Reboot oder be root, das ist hier die Frage.
|
BID = 755650
DonComi Inventar
Beiträge: 8605 Wohnort: Amerika
|
Siehe oben.
Klarheit in der (Schrift)Sprache ist immer von Vorteil, vor allem in unserem Bereich .
Denn:
Zitat :
|
Allerdings gibt es da ein Problem. Die Kommunikation läuft über Hex-Zahlen ab.
|
ist gar kein Problem.
Eigentlich reden wir immer über Nullen und Einsen, nur stellt man ein Byte selten in seiner Binärnotation dar (das machen Programmierer, die Wert darauf legen, dass keiner ihr Programm versteht oder die es einfach nicht besser wissen...), sondern entweder in Dezimalschreibweise (z.B. in mathematischen Ausdrücken, für Zähler und ähnliches) oder aber zur Basis 16, also hexadezimal. Das hat den Vorteil, dass das geübte Auge sofort die Bitkombinationen sieht (2^4 = 16) und das Datentypen i.d.R. Vielfache von 8 Bit sind, man also für 8 Bit-Werte zwei Stellen, für 16 Bit vier Stellen, für 32 Bit acht Stellen usw. notieren kann.
_________________
|
BID = 756612
MechMac666 Gesprächig
Beiträge: 197 Wohnort: Salzkotten
|
Hallo,
ich habe es nun soweit hinbekommen, das zum testen die HEX-Werte vom µC an einen Pc gesendet werden und auch fast vollständig ankommen.
Genaugenommen wird immer das 0x00 verschluckt. Egal wann ich es sende und wie oft. Keines kommt an.
Hier etwas mehr Quelltext. Vielleicht hilft`s ja.
#define UART_BAUD_RATE 19200L
#define UART_BAUD_CALC(UART_BAUD_RATE,F_CPU) ((F_CPU)/((UART_BAUD_RATE)*16L)-1L)
void USART_putc(uint8_t byte)
{
while(bit_is_clear(UCSR0A,UDRE0)); //warten auf Datenregister empty
UDR0=byte;
}
Und in der Main:
UBRR0H = (uint8_t) (UART_BAUD_CALC(UART_BAUD_RATE,16000000)>>8);
UBRR0L = (uint8_t) UART_BAUD_CALC(UART_BAUD_RATE,16000000);
UCSR0B = (1<<RXEN0) | (1<<TXEN0) | (1<<RXCIE0);
UCSR0C = (1 << UCSZ01) | (1 << UCSZ00);
Mich würde interessieren, warum das 0x00 wohl verschluckt wird.
Wird es vielleicht als Stopp oder so interpretiert?
Gruß, Andreas
|
BID = 756614
DonComi Inventar
Beiträge: 8605 Wohnort: Amerika
|
NUL (0x00) wird auf seriellen, zeilenbasierten Terminals meistens verworfen.
Je nach Betriebssystem musst du die Schnittstelle anders öffnen.
Man bezeichnet diesen Modus meist als Raw-Modus, weil die Bytes weder interpretiert werden (z.B. EOF, INT, ...) noch Bytes aus dem Datenstrom entfernt werden.
Womit ließt du denn die serielle Schnittstelle aus?
VB?
_________________
|
BID = 756632
MechMac666 Gesprächig
Beiträge: 197 Wohnort: Salzkotten
|
Die Ausgangssituation ist folgende:
Im Grunde kommuniziert momentan der Computer mit der Kamera.
Jetzt kommt mein µC und soll den PC ersetzen.
Da ich aber die Kommunikation zunächst testen möchte, schicke ich den Kram vom µC zum PC und lasse es mir dort anzeigen.
Das "Dummy-Programm" ist in Delphi geschrieben. Damit öffne ich den seriellen Port. Es ließt aber nur Strings aus.
Das eigentliche erfassen mache ich mit Serial Port Monitor. Der bekommt das alles mit, wenn es denn gesendet wird.
Für den ersten Test hatte ich zwischen PC und Kamera auch den Serial Port Monitor und dort wurden die 0x00 definitiv übertragen. Also irgendwie muss das ja dann gehen. Die Kamera braucht das zum initialisieren der externen Steuerung.
Gruß
|
BID = 756641
DonComi Inventar
Beiträge: 8605 Wohnort: Amerika
|
Moin,
Ja, sicherlich geht das.
Die Nullbytes werden ganz normal gesendet.
Sie werden nur von deinem Programm nicht angezeigt, da die zugrundeliegende Schicht die Daten interpretiert oder zumindest NUL aussortiert.
NUL hat ja einige Bedeutungen, eine wäre z.B. „diese Information ist keine“, also ein Füllbyte ohne Informationsgehalt. Eine andere Bedeutung hat NUL als Abschluss für Strings.
Mach dir da aber keinen Kopp, weder die Kamera noch den µC interessiert das.
Diese ganzen Zeichenverarbeitung und -ersetzung/-entfernung findet auf Betriebssystemebene statt.
_________________
|
BID = 756702
MechMac666 Gesprächig
Beiträge: 197 Wohnort: Salzkotten
|
Das klingt plausibel. Aber dennoch finde ich folgendes merkwürdig: Wenn ich anstelle des µC die Kamera anschließe und das Delphi-Programm gegen das original Steuerungsprogramm tausche und nun dieser Verbindung mit dem Serial Port Monitor lausche, werden die 0x00 angezeigt.
Ich habe auch mal versucht ein Scope (Rigol DS1052E) anzuschließen und habe gehofft da etwas zu sehen, aber außer einem Ausschlag war da nichts. Vermutlich gibt es da Trick 17, oder das Scope ist zu langsam dafür. Oder aber es wird die Gegenstelle, in dem Fall der PC benötigt. Ich habe das Scope nämlich an TX und GND am µC-Board angeschlossen, ohne Pc am anderen Ende.
Das Problem ist ja, das ich das nicht testen kann. Die Kamera würde natürlich auf das 0x00 antworten, aber da sind meine 100 Probleme wieder. So wie die Senderoutine nur Char sendet, empfängt die Empfangsroutine nur Char. Klar, geht das byteweise bevor die Char-Kette gebildet wird, ich weiß nur nicht wie ich das abfragen soll.
Woher weiß ich wann die Antwort vollständig ist?
Das werden unübersichtlich viele Fehlerquellen, daher muss ich, bevor ich mich um das empfangen kümmere, sicher sein das das 0x00 tatsächlich gesendet wird.
|
BID = 756721
QuirinO Schreibmaschine
Beiträge: 2205 Wohnort: Behringersdorf
|
Zitat :
|
Ich habe auch mal versucht ein Scope (Rigol DS1052E) anzuschließen ... oder das Scope ist zu langsam dafür.
|
Das Scope ist sicher nicht zu langsam, hab das auch hier stehen und damit RS232 debugt.
Hast du beide Leitungen angeschlossen, mach das doch mal mit beiden Kanälen, der richtige Trigger ist auch wichtig. Eventuell hast du das Signal einfach verpasst oder die Zeitablenkung falsch eingestellt.
|
BID = 756788
DonComi Inventar
Beiträge: 8605 Wohnort: Amerika
|
Also ich finde das irgendwie widersprüchlich. Wenn Serial Port Monitor das 0x00 ließt, dann wird es auch richtig vom µC gesendet. Wenn das Delphi-Programm 0x00 nicht ließt, liegt das zu 99% daran, dass die Bytes noch anderweitig interpretiert werden - die serielle Schnittstelle wird im Prinzip behandelt wie eine Datei und dort gibt es auch Zeichen mit bestimmten Bedeutungen. In seriellen Terminals wird z.B. ein Zeichen als EOF vereinbart, also End of File. Das bedeutet, wenn dieses Zeichen empfangen wird, das Ende der „Datei“ erreicht ist und sie geschlossen wird.
Aber bevor ich weiter , wie sieht denn die Beschaltung zwischen µC und PC aus und in welchem Modus wird die Schnittstelle genau geöffnet? Handshake?
Ist das eine via USB emulierte COM-Schnittstelle oder eine richtige? Hast du einen Pegelwandler verschaltet? Ohne kann es zu Problemen kommen.
Zitat :
|
So wie die Senderoutine nur Char sendet, empfängt die Empfangsroutine nur Char. Klar, geht das byteweise bevor die Char-Kette gebildet wird, ich weiß nur nicht wie ich das abfragen soll.
Woher weiß ich wann die Antwort vollständig ist?
|
Da gibt es zig Möglichkeiten - die einfachste und gängigste ist es, die Daten in einem Software-FIFO zu speichern und z.B. nach N Bytes den gesamten Speicherinhalt mit einem fixen Wert zu vergleichen (memcmp).
memcmp daher, weil hier auch binäre Werte verglichen werden müssen. strncmp würde man für reine ASCII-Zeichenketten verwenden.
Eine andere Möglichkeit besteht darin, nach jedem empfangenen Byte bestimmte Zustände zu speichern, bis dann irgendwann das Vergleichskriterium (z.B. erkannte Bytesequenz 0xaa 0x00 0xba 0x11) zutrifft.
Letztere Methode ist schneller und effizienter, aber nicht immer ganz durchsichtig von der Programmierung.
Also, irgendwie so:
static char sw_fifo[32];
static uint8_t index = 0;
...
ISR(uart)
{
if(index==sizeof sw_fifo) { /* FIFO voll */ }
else sw_fifo[index++] = UDR;
}
Ob man einen Puffer verwendet hängt auch vom jeweiligen Ziel-µC ab, einige haben ja enorm wenig SRAM.
_________________
|
BID = 756799
MechMac666 Gesprächig
Beiträge: 197 Wohnort: Salzkotten
|
@DonComi
Das hast du falsch verstanden. Das Delphi Programm empfängt das 0x00 in keinem Fall. Ich verwende es ausschließlich zum öffnen des Ports. Das Betrachten der Daten mache ich in jedem Fall mit Serial Port Monitor.
Ich formuliere meine Aussage mal anders.
Wenn ich die Kamera und den PC verbinde und das original Steuerungsprogramm verwende und dann mit Serial Port Monitor lausche, werden die 0x00 angezeigt.
Wenn ich die den µC und den PC verbinde und das Delphi Programm zum Port öffnen verwende und dann mit Serial Port Monitor lausche, werden die 0x00 nicht angezeigt.
@QuirinO
Ich habe quasi einfach TX und GND über Kanal 1 angezapft. Wo soll ich denn den zweiten Kanal anschließen? Der wäre doch für die Zeitachse, oder? Ist die Zeit nicht schon durch die Dauer zwischen den Impulsen bestimmt?
Trigger und Zeitablenkung stehen auf Werkseinstellung, ich habe keine Infos dazu gefunden, die beschreiben wozu das gut sein soll wenn man das verstellt.
|
BID = 756857
DonComi Inventar
Beiträge: 8605 Wohnort: Amerika
|
Zitat :
|
Trigger und Zeitablenkung stehen auf Werkseinstellung, ich habe keine Infos dazu gefunden, die beschreiben wozu das gut sein soll wenn man das verstellt
|
Warum schickst du die Daten nicht einfach an die Kamera und guckst, ob es klappt? Habe dir ja oben gezeigt, wie man das machen kann...
_________________
|
|
Zum Ersatzteileshop
Bezeichnungen von Produkten, Abbildungen und Logos , die in diesem Forum oder im Shop verwendet werden, sind Eigentum des entsprechenden Herstellers oder Besitzers. Diese dienen lediglich zur Identifikation!
Impressum
Datenschutz
Copyright © Baldur Brock Fernsehtechnik und Versand Ersatzteile in Heilbronn Deutschland
gerechnet auf die letzten 30 Tage haben wir 19 Beiträge im Durchschnitt pro Tag heute wurden bisher 13 Beiträge verfasst © x sparkkelsputz Besucher : 182125884 Heute : 5184 Gestern : 5915 Online : 527 4.10.2024 22:27 5 Besucher in den letzten 60 Sekunden alle 12.00 Sekunden ein neuer Besucher ---- logout ----viewtopic ---- logout ----
|
xcvb
ycvb
0.0456540584564
|