Hallo zusammen,
aktuell arbeite ich für die Hochschule an einem kleinen Projekt mit
Microcontrollern.
Ich habe hierzu einen Arduino Uno mit ATmega328p, programmiere aber
nicht über das Arduino Framework sondern in reinem C mit avr-gcc.
Mein Ziel ist es, Daten (Texte) per Kabel an von einem RaspberryPi an
den Arduino zu senden und diese dort zu verarbeiten. Zum Testen möchte
ich das empfangene Byte einfach auf 8 LEDs darstellen.
Ich habe also den Ground des Raspis und des Arduino verbunden und
außerdem TX des Raspi mit RX des Arduino.
Wenn ich nun im Raspi einen Minicom öffne und Tasten drücke, gehen zwar
LEDs an, jedoch sind es bei fast allen Buchstaben alle LEDs, bis auf die
letzte. (1111110) Nur bei einigen Buchstaben, zum Beispiel h,j ,k l,
gehen 2 LEDs aus. Dann wird immer 10011110 ausgegeben.
Wenn ich das ganze über das Arduino Framework mache, funktioniert es
wunderbar und ich kann auf unterschiedliche Buchstaben reagieren.
Mein Fehler wird also vermutlich in der Initialisierung des UART oder
der Verarbeitung liegen. Meinen Fehler finde ich jedoch nicht. Ich habe
ihn mit vielen Beispielcodes, unter anderem aus diesem Forum,
verglichen.
Ich hoffe, dass ihr mir helfen könnt :)
Viele Grüße
Loris,
Hier noch mein Quellcode:
Loris I. schrieb:> void rx_to_led(int rx){> // Maps the parameter to the 8 output-LEDs> int b = rx >> 2;> int d = (rx & 3) << 6;>> PORTB = b;> PORTD = d;> }
Stimmt diese Funktion? Hast du die mal mit verschiedenen festen Werten
getestet?
Vielen dank für die viele schnelle Hilfe!
Die Funktion rx_to_led habe ich mit verschiedenen werten getestet. Sie
funktioniert.
Als F_CPU habe ich 16000000UL gesetzt, da das in vielen Beispielen mit
diesem µC auch gesetzt war. Wobei ich gestehen muss, dass ich (noch)
nicht genau verstehe was das genau bedeutet.
Ich lese mich da gerade ein bissche ein und ich kann scheinbar über
CKSEL0..3 die Clock setzen.
Ich könnte mir vorstellen, dass der Arduino Bootloader hier vielleicht
verschiedene Werte setzt.
Dem werde ich auf den Grund gehen.
Loris I. schrieb:> Die Funktion rx_to_led habe ich mit verschiedenen werten getestet. Sie> funktioniert.
Meine C Kenntnisse sind jetzt zwar etwas eingerostet aber das du hier
einem 8 Bit Port ein int zuweist müsste aber mindestens eine Warning
erzeugen.
Compiliere mal mit allen Warnings an.
Eine Kleinigkeit ist mir gerade noch aufgefallen, die vielleicht auch
interessant ist:
Beim senden von 'o' leuchtet zuerst 1111110 auf. Beim wiederholen dann
nur noch 10011110. Bei weiteren Wiederholungen blinken dann die 2. und
3. LED ganz kurz auf.
Loris I. schrieb:> Vielen dank für die viele schnelle Hilfe!>> Die Funktion rx_to_led habe ich mit verschiedenen werten getestet. Sie> funktioniert.>> Als F_CPU habe ich 16000000UL gesetzt, da das in vielen Beispielen mit> diesem µC auch gesetzt war. Wobei ich gestehen muss, dass ich (noch)> nicht genau verstehe was das genau bedeutet.
Das bedeutet, dass dein M328p mit 16Mhz läuft. Und das stimmt ja auch.
Auf einem Arduino Uno ist ein Keramik Resonator mit 16Mhz verbaut.
> Ich lese mich da gerade ein bissche ein und ich kann scheinbar über> CKSEL0..3 die Clock setzen.
Vorsicht.
Dein Uno ist schon mit der richtigen Einstellung gekommen. Das passt
schon.
> Ich könnte mir vorstellen, dass der Arduino Bootloader hier vielleicht> verschiedene Werte setzt.
Nein. Der Boorloader kann diese Werte nicht ändern.
Wozu auch? Der Resonator als Bauteil hat nun mal 16Mhz.
> Dem werde ich auf den Grund gehen.
Dreh erst mal deine Senderichtung um.
Lass den Arduino senden und sieh dir am Pi im Terminalprogramm an, was
da rauskommt. Es ist immer eine gute Idee, zuerst den Teilnehmer
empfangen zu lassen, bei dem man das Empfangene einfach sichtbar machen
kann und dem man soweit vertraut, das alles in Ordnung ist.
Steht diese Kommunikationsrichtung erst mal, dann funktioniert die
andere Richtung normalerweise sofort. Ist auch logisch: wird ja in
beiden Fällen die gleiche Baudrate benutzt.
Karl Heinz schrieb:> Das bedeutet, dass dein M328p mit 16Mhz läuft. Und das stimmt ja auch.> Auf einem Arduino Uno ist ein Keramik Resonator mit 16Mhz verbaut.
Und wenn ich den internen Resonator verwenden möchte? Der Arduino ist
nur zum Prototyping gedacht. Später wollen/sollen wir auf einen
einzellnen Microcontroller umsteigen.
> Dreh erst mal deine Senderichtung um.> Lass den Arduino senden und sieh dir am Pi im Terminalprogramm an, was> da rauskommt. Es ist immer eine gute Idee, zuerst den Teilnehmer> empfangen zu lassen, bei dem man das Empfangene einfach sichtbar machen> kann und dem man soweit vertraut, das alles in Ordnung ist.> Steht diese Kommunikationsrichtung erst mal, dann funktioniert die> andere Richtung normalerweise sofort. Ist auch logisch: wird ja in> beiden Fällen die gleiche Baudrate benutzt.
Daran hatte ich auch schon gedacht. Das Problem ist nur, dass ich keinen
Spannungsteiler zur Hand habe, da der Arduino mit 5V läuft und der RPi
mit 3,3V könnte der Rückweg problematisch werden.
Loris I. schrieb:> Karl Heinz schrieb:>>> Das bedeutet, dass dein M328p mit 16Mhz läuft. Und das stimmt ja auch.>> Auf einem Arduino Uno ist ein Keramik Resonator mit 16Mhz verbaut.>> Und wenn ich den internen Resonator verwenden möchte?
Dann musst du an die Fuses ran.
Aber so wie der Ardunio geliefert wurde, läuft er mit 16Mhz durch den
externen Resonator. Und genau das ist auch der Zweck von F_CPU: den
Compiler darüber zu informieren, dass der µC mit 16Mhz rennt.
Das ändert aber am Grundproblem nichts.
Mit dem internen Generator (der kein Resonator ist), ist die Genauigkeit
der Taktfrequenz schlechter als mit dem externen Generator. Wenn du mit
dem Resonator keine saubere UART hinkriegst, dann kriegst du es mit dem
interen Takt auch nicht hin.
> Daran hatte ich auch schon gedacht. Das Problem ist nur, dass ich keinen> Spannungsteiler zur Hand habe, da der Arduino mit 5V läuft und der RPi> mit 3,3V könnte der Rückweg problematisch werden.
Dann besorg dir 2 Widerstände.
Das Stochern im Nebel muss aufhören. Raten ist ein schlechter Ratgeber,
auch wenns manchmal nicht anders geht.
Loris I. schrieb:> Und wenn ich den internen Resonator verwenden möchte? Der Arduino ist> nur zum Prototyping gedacht. Später wollen/sollen wir auf einen> einzellnen Microcontroller umsteigen.
Es gibt keinen internen Resonator, nur einen RC-Oszillator, der im
allgemeinen nix für serielle Kommunikation taugt, zu ungenau.
Über den ISP-Anschluss kann man das alles ändern und dauch dafür sorgen,
dass gar nichts mehr geht.
Ein Bootloader ist sicherer, da kann man nichts verpfuschen, da man
keinen Zugriff auf die Fuses hat. Ein ATM328 von der Stange wird
allerdings keinen Bootloader haben, da muss dann der ISP ran.
Ich habe nun den Arduino über den 3,3V Pin des Raspi betrieben. So
brauche ich keinen Spannungsteiler. Für LEDs scheint es dann nicht mehr
zu reichen, aber die brauche ich ja vorerst nicht unbedingt.
Was ich gesendet habe, habe ich den Atmega direkt zurücksenden lassen.
Minicom gibt mir beim senden von a-z folgendes:
yz{|}~hijklmnoxyz{|}~xyz