Hey Für mein Technikerprojekt will ich 3 werte über die C# oberfläche an den Atmega8 senden und diese dort verarbeiten. Den Atmega8 (AVR board) programmiere ich in C über das AVR studio 6. Nach etlichen Forenbeiträgen komme ich mir irgendwie doof vor weil ichs nicht raffe. Die Kommunikation c# seitig funktioniert schonmal. Jedoch bekomme ich die Werte nicht verarbeitet bzw Variablen zugewiesen. Hilfe wäre echt toll, denn ich verzweifel und mir rennt die zeit weg... Danke schonmal :-P
Gast
#3019427
für eine hilfeleistung solltest du dein problem genauer beschreiben ... ausser das du offensichtlich im stress bist, wissen wir nicht wirklich viel mehr! -> sourcecode?
Tobias Giesen schrieb: > Die Kommunikation c# seitig funktioniert schonmal. woran erkennst Du das?
Ich bekomme das angehängte bild ausgtegeben... nur leider empfange ich
nicht die zeichen, die ich sende :-/
also mein Programm im uC (als Testprogramm zum senden und empfangen von
zeichen):
/*
* UART_CPP.cpp
*
* Created: 23.01.2013 09:28:50
* Author: K
Terminal_MCT
*/
#include <avr/io.h>
#define F_CPU 3686400L //Quarz = 3.6864 Mhz
void UARTInit()
{
UBRRL=0x17; //Baudrate 9600
UCSRB=0x18; //RXEN=1; TXEN=1;
UCSRC=0x86; //Asynchroner Modus, keine Parität, 8 Datenbits,
1Stoppbit
}
uint8_t UARTGetChar()
{
while(!(UCSRA&(1<<RXC))); //warte auf Empfang
return UDR; //empfange Daten
}
void UARTPutChar(uint8_t val)
{
while(!(UCSRA&(1<<UDRE))); //warte auf freies Senderegister
UDR=val; //sende Daten
}
int main(void)
{
DDRD |=(1<<PD2);
UARTInit();
uint8_t z;
while(1)
{
z=UARTGetChar(); //warte auf empfangenes Zeichen
UARTPutChar(z); //sende Zeichen
//if (z==49) PORTD|=(1<<PD2); else PORTD&=~(1<<PD2); //zb led an
}
return 0;
}
Gast
#3019481
Bekommst Du wirklich falsche Zeichen zurück oder stellt sie Dein C#-Programm eventuell falsch dar? Was passiert, wenn Du mit einem guten Terminalprogrammie wie "hterm" Zeichen hin- und hersendest? Funktioniert das?
Tobias Giesen schrieb: > Ich bekomme das angehängte bild ausgtegeben... nur leider empfange ich > nicht die zeichen, die ich sende :-/ Dann nimm mal eine Fehlerquelle weg, und ersetze dein C# Programm durch einer Terminalprogamm am PC. Denn von dem weißt du erst mal, dass es korrekt funktioniet. Weiters lässt du den AVR erst mal nur senden. Das was der AVR sendet, muss im Terminalprogramm sauber ankommen. Erst dann, wenn das so ist, hast du eine gewisse Sicherheit, dass die kleinen Fallen wie falsche Taktfrequenz und Baudrate ausgemerzt sind und du dir zumindest um diese Teile keine Sorgen mehr machen brauchst. Immer als erstes so weit es geht abspecken. Je weniger du im Gesamtsystem hast, was schief gehen kann - je weniger potentielle Fehlerquellen es gibt - desto besser. Und dann immer nur wieder ein neues Teil, mit einer möglichen Fehlerquelle mit dazunehmen und nachsehen, ob immer noch alles funktioniert. Der Hauptfehler, den Neulinge gerne machen, besteht darin, dass sie die Sache unterschätzen und gleich mit zu komplexen Beispielen anfangen. Und dann nicht wissen, wo sie mit Fehlersuche anfangen sollen, weil der Fehler nicht eindeutig zuordenbar ist und im Grunde überall stecken kann. Da hilft nur: abspecken, abspecken, abspecken. Auf lange Sicht ist man schneller, wenn man mit scheinbar trivialen Setups anfängt und sich von dort mit vielen testbaren Zwischenstufen in Richtung endgültiges Ziel vorarbeitet.
bei hterm bekomm ich auch nur quatsch...
Gast
#3019509
Tobias Giesen schrieb: > bei hterm bekomm ich auch nur quatsch... Laß Dir das als HEX anzeigen, mit ASCII kommst Du bei der Fehlersuche nicht weit!
Tobias Giesen schrieb: > bei hterm bekomm ich auch nur quatsch... Dann würde ich mal den Standardfehler annehmen und behaupten, dass das hier
1 | |
nicht stimmt. Zu 98% ist es dieser Fehler. Hast du denn schon kontrolliert, ob dein µC tatsächlich auf 3.6864Mhz läuft? AVR Checkliste: UART/USART
Gast
#3019519
PS: Was ist mit dem Watchdog?
hab mir das mal in HEx anzeigen lassen, mit dem ergebnis das ich egal was ich ein gebe immer den gleichen Wert (F8) zurück bekomme :-/ Die Taktrate ist richt... also laut beschreibung des AVR Boards...
Gast
#3019533
Hi >bei hterm bekomm ich auch nur quatsch... Die HEX-Darstellung wäre sinnvoller gewesen. Sicher, das dein AVR wirklich mit 3.6864 Mhz lauft? MfG Spess
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
Bitte nicht. Schau ins AVR-GCC-Tutorial/Der UART, wie man sowas schreiben kann, so dass es auch lesbar bleibt. Das hat schon seinen Grund, warum wir das propagieren.
Tobias Giesen schrieb: > Die Taktrate ist richt... also laut beschreibung des AVR Boards... Der Worte hör ich wohl, allein mir fehlt der Glaube. Nicht 'laut Beschreibung' - kontrolliere es! Das dauert keine 5 Minuten und dann WEISZT du es mit Sicherheit! Mag ja sein, dass an diesem Punkt alles korrekt ist - Vertrauen ist gut. Kontrolle ist besser.
Gast
#3019554
Schick doch mal einen konstanten Wert zurück:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
Bronco schrieb: > Schick doch mal einen konstanten Wert zurück: > >
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
wenn ich z einen festen wert zuordne, bekomm ich gar nichts mehr zurück... so langsam nervt mich dieses Programm :D
Gast
#3019590
Da gibt es ein neues µC Buch ( ISBN-10: 3645651314 ), in dem für den ATmega 8 die Serielle ausprogrammiert ist und auch der Sourcecode für ein C# Terminal angegeben ist. Sehr innovatives Buch, schau einmal das Inhaltsverzeichnis an.
Tobias Giesen schrieb: > wenn ich z einen festen wert zuordne, bekomm ich gar nichts mehr > zurück...
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
> so langsam nervt mich dieses Programm
Aber nur weil du nicht systematisch vorgehst.
Du könntest schon längst fertig sein, wenn du nicht so stur auf deinem
Standpunkt beharren würdest.
Gast
#3019604
Oder noch simpler:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
Blinkt die LED mit 2Hz? Nein: -> falsche Taktfrequenz -> Watchdog -> WTF? Prüfe die Fuses! Prüfe den Watchdog!
sooo hab jetzt mal nen festen wert ausgeben lassen... stelle ich im c programm den festwert 5 ein, bekomme ich bei der kommunikation eine 8 ausgegeben :-/
Gast
#3019628
Tobias Giesen schrieb: > wenn ich z einen festen wert zuordne, bekomm ich gar nichts mehr > zurück... Tobias Giesen schrieb: > stelle ich im c programm den festwert 5 ein, bekomme ich bei der > kommunikation eine 8 ausgegeben :-/ ???
hast du jetzt endlich mal den Frequnzcheck gemacht? Aus dem Checklisten Link
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | |
26 | |
Für den Port musst du noch was einstellen, wo im Idealfall sowieso schon eine LED drann hängt, bzw. wo du einfach mal eine kurzfristig anklemmen kannst. Wie oft blinkt die LED in 10 Sekunden? Armbanduhr-Genauigkeit genügt. Das ist doch nicht so schwer. Und wenn diese Frage beantwortet ist, dann wissen wir, ob die 3.6864 Mhz stimmen, oder ob das noch die Default 1Mhz ab Werk sind, die da arbeiten. Und ohne das dieses ein für allemal 100% sicher abgeklärt ist, brauchen wir da gar nicht weiter machen. Diesen Test MUSS dein µC bestehen!
Karl Heinz Buchegger schrieb: > Tobias Giesen schrieb: > >> wenn ich z einen festen wert zuordne, bekomm ich gar nichts mehr >> zurück... > > >
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
hier bekomme ich lediglich ne 8 raus!
so... LED Blinkt in 10sek 2 mal! sry wenns manchmal was länger dauert...
Gast
#3019659
Hi
>hier bekomme ich lediglich ne 8 raus!
Ich könnte wetten, dein ATMega läuft mit 1MHz.
MfG Spess
Tobias Giesen schrieb: > so... LED Blinkt in 10sek 2 mal! Womit der Beweis erbracht ist. Dein µC läuft auf 1Mhz und nicht auf 3.6864Mhz. Soviel zum Thema: "eigentlich laut Beschreibung". Wenn du die Fuses dann auf Quarzverwendung (du hast doch einen Quarz drann, oder nicht?) umgefused hat, dann muss dein µC in 10 Sekunden genau 10 Blinker machen. Nur dann stimmt die F_CPU angabe mit der Realität überein. Soweit waren wir vor anderthalb Stunden schon mal. Hättest du den Test gemacht, dann hättest du dir anderthalb Stunden 'nerven' gespart.
Karl Heinz Buchegger schrieb: > Wenn du die Fuses dann auf Quarzverwendung (du hast doch einen Quarz > drann, oder nicht?) umgefused hat, dann muss dein µC in 10 Sekunden > genau 10 Blinker machen. Natürlich 5 komplette Blinker. jeweils 1 Sekunde an, 1 Sekunde aus. In 10 Sekunden geht das logischerweise nur 5 mal.
Gast
#3019681
Tobias Giesen schrieb: > Jedoch bekomme ich die Werte nicht verarbeitet bzw Variablen zugewiesen. Ob dann diese Behauptung noch zu halten ist?
Gast
#3019689
Probier doch mal als erstes das USART_Init Beispiel aus dem Datenblatt. Probiers einfach, wenns dann nicht geht kann man weiter suchen...
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
kann es sein das du den falschen Pin als ausgang setzt? Du setzt PD2... TxD ist aber PD1 / RxD ist PD0 Oder ist PD2 für was anderes gut? Das würde (vielleicht?!) erklären weshalb du immer den gleichen wert bekommst... Grüße
Gast
#3019694
Hi >kann es sein das du den falschen Pin als ausgang setzt? >Du setzt PD2... TxD ist aber PD1 / RxD ist PD0 >Oder ist PD2 für was anderes gut? Mit 'UCSRB = (1<<RXEN)|(1<<TXEN);' übernimmt die UART die Kontrolle über das TXD- und das RXD-Pin. Die Einstellung im DDR-Register spielt keine Rolle mehr. MfG Spess
sooo... jetzt bin ich fast schon glücklich :D
ich bekomm jetzt auch in meinem eigenen c# programm das gleiche raus was
ich eingebe...
next problem... mit
z=UARTGetChar();
weise ich doch den in c# eingegebene wert der variablen z zu oder!?
wenn ich nun allerdings nicht ein sondern 3 textfelder in c# habe und
dort variablem übergeben will, wie sieht das dann aus?
uint8_t z, t, x;
while(1)
{
z=UARTGetChar();
t=UARTGetChar();
x=UARTGetChar();
!? oder ist das quatsch?
Lasst ihn doch erst mal seinen Quarz aktivieren. Danach wird die Init mal vernünftig unter Verwendung der F_CPU und der zu erzielenden Baudrate geschrieben (obwohl die bisher verwendete Konstante gestimmt hätte). Und dann ... wird er sehen, dass seine UART plötzlich 'magisch' funktioniert. Wenn das Senden klappt, dann wird auch das Empfangen bzw. Zurücksenden mehr oder weniger auf Anhieb klappen (sein Kabel bzw. der MAX232 dürfte ja in Ordnung sein), und dann wird auch sein C# Programm höchst wahrscheinlich funktionieren. Und die Rate der Nicht-funktionierenden UARTS aufgrund falscher µC-Taktrate hebt sich von 99.950005% auf 99.950006%.
Tobias Giesen schrieb: > sooo... jetzt bin ich fast schon glücklich :D > > ich bekomm jetzt auch in meinem eigenen c# programm das gleiche raus was > ich eingebe... > next problem... mit > z=UARTGetChar(); > weise ich doch den in c# eingegebene wert der variablen z zu oder!? Nö. Dein C# schickt ein Zeichen über die Schnittstelle. WO auch immer dieses Zeichen herkommt, was es auch immer mit diesem Zeichen für eine Bewandtniss hat. Der AVR kann das nicht wissen. Für ihnen sind das einfach nur Bytes, die aus der UART herauspurzeln. Von C# oder gar Variablen oder gar Textfeldern weiß der nichts. > wenn ich nun allerdings nicht ein sondern 3 textfelder in c# habe und > dort variablem übergeben will, wie sieht das dann aus? Dann musst du eben irgendetwas auf der Seriellen Schnittstelle mitsenden, anhand dessen der AVR unterscheiden kann, welcher WErt was darstellen soll. WEnn du zb aus ASCII übertragung setzt, dann bietet es sich zb an, in den Text gewisse 'Hinweise' einzubauen. Zb H=12; und das steht beispielsweise für "Set Hour to 12 o'clock", also die Aufforderung die AVR interne Uhr in den Stunden auf 12 zu setzen. > while(1) > { > z=UARTGetChar(); > t=UARTGetChar(); > x=UARTGetChar(); > > !? oder ist das quatsch? sobald aus irgendeinem Grund 1 Zeichen verloren geht, kommt alles durcheinander. Und: bist du sicher, dass dir 8 Bit reichen werden, um deine Zahlen auszudrücken? Binär zu übertragen ist schön und vor allen Dingen schnell. Aber wenn man keine Bytewerte hat, die man zur Synchronisierung benutzen kann, dann wirds schnell mit dem Protokoll aufwendig. Übertragung per Text hat zwar den Vorteil, dass die Protokolle einfach zu implementieren sind (denn für Steuerungszwecke hat man genügend Bytewerte frei), dafür ist die Auswertung etwas aufwändiger. Aber so wild auch wieder nicht. Und man hat den Vorteil: Das PC-Frontend muss nicht fertig sein. Denn ob ein Benutzer am Terminal H=12 (gefolgt von Return) eingibt, oder ab ein Programm einen derartigen String schickt: dem AVR ist das ja egal. Der sieht ja nicht, wer da am anderen Ende mit dem Spannungspegel wackelt.
Gast
#3019724
Tobias Giesen schrieb: > wenn ich nun allerdings nicht ein sondern 3 textfelder in c# habe und > dort variablem übergeben will, wie sieht das dann aus? Nur so am Rande: Ist Dir klar, was für Datentypen deine "Textfelder" haben bzw. an den µC schicken? Ist Dir klar, daß es Datentypen gibt, die größer als 1 Byte sind? Ist Dir klar, daß die Zahl "124532552545" (aus Deinem Bild oben) in ASCII 12 Bytes enthält? Ist Dir klar, ob Du nicht vielleicht Strings übertragen willst?
ok... nach viel bahnhof in meinem kopf werde ich mal was konkreter :D ich muss drei wunschfülllstände von Flüssigkeiten übertragen... also 3 Werte die wohl alle 2 bis maximal 3 Stellig sind... leider habe ich null plan von der übertragung (wie ihr vll schon gemerkt habt) bzw obs vll sinnvoller ist strings zu verwenden... so langsam habe ich auch das gefühl das mein betreuungslehrer es lustig fand als er sagte es wäre ganz einfach mit dem C' Programm veriablem im uC zu verändern^^ also schließe ich aus dem letzten beitrag das es vll sinnvoller ist das ganze in sogenannten "Strings" zu übergeben?!
Tobias Giesen schrieb: > also schließe ich aus dem letzten beitrag das es vll sinnvoller ist das > ganze in sogenannten "Strings" zu übergeben?! Für einen Anfänger hätte ich gesagt: Ja. Das lässt sich PC-seitig leicht generieren, AVR seitig leicht empfangen und wenn man seine String-Funktionen kennt, lässt es sich auch AVR-seitig leicht wieder zerlegen und in Zahlen verwandeln. Du musst das ja nicht so aufwendig machen. Definiere einfach: Jede 'Anweisung' an den AVR ist eine Zeile. Also eine Abfolge von Charactern, die mit einem Carriage Return (du kannst auch jedes andere Zeichen wählen, ';' ist zb sehr beliebt) endet. Jede Anweisung beginnt immer mit einem Buchstaben, wobei der Buchstabe ('A' bis 'Z', nur Grossbuchstaben erlaubt) eine Aussage darüber macht, welcher Füllstand zu ändern ist. Die restlichen Character bis zum Zeilende sind dann Ziffern, die zusammengenommen die einzustellende Zahl ergeben. zb (ich verwende ';' als Ende-Zeichen) A649; bedeutet: setze Füllstand 1 auf den Wert 649 B98; bedeutet: setze Füllstand 2 auf den Wert 98 C?; bedeutet: gib mir den Wert für Füllstand 3 Das kannst du zb leicht mit dem hTerm erst mal ohne PC-Programm testen, einfach indem du die Texte eintippst. Und Programmmässig sind solche Dinge auch leicht zu erzeugen. Auf dem AVR läuft einfach eine Routine, die Zeichen die reinkommen an einen String anhängt, solange bis es den ';' erkennt. Ist der erkannt, dann hat es einen kompletten String und macht sich daran, diesen zu zerlegen. Das ist aber einfach, denn das erste Zeichen im String sagt dir, mit welchem Füllstand du es zu tun hast, die weiteren Zeichen, was damit zu tun ist. Also: frisch ans Werk und für den AVR mal eine Funktion geschrieben, die solange Zeichen in einem char-Array sammelt, bis ein ';' daher kommt und wenn das der Fall ist, einen C-String draus macht und einfach mal den String zurückschickt. (Du merkst schon: dein C# Programm kannst du erst mal zur Seite legen. Das machst du alles PC-seitig erst mal mit dem Terminal-Programm. Getreu dem Motto: kein 2-Fronten-Krieg. Immer nur 1 Baustelle)
Gast
#3019765
Was Du brauchst, nennt sich "Protokoll". Ein Protokoll (in diesem Zusammenhang) definiert, in welcher Form Informationen kommuniziert werden. D.h. Du mußt Dir ein Protokoll ausdenken, was Deinen Ansprüchen genügt und dann dieses gleichermaßen in Deinem C#-Programm als auch im µC umsetzen. Beispiel: Dein Telefon klingelt und der Anrufer sagt "10" und legt auf. Was bedeutet das jetzt? 10 Käsekuchen? Treffen um 10:00? Daß er Dir 10 Euro geben will oder daß Du ihm 10 Euro geben sollst? Du siehst, Daten sind nichts wert, wenn nicht klar ist, was sie bedeuten.
10 bedeutet immer das ich 10€ bekomme :D ok...vielen vielen dank schonmal für die hilfe! allein wäre ich jetzt immernoch bei 1Mhz und würde denken ich sage dem uC das z=400 ist^^... ich werde mich heute und morgen mal an den code setzen und versuchen das hier kommunizierte zu verarbeiten^^ mittwoch melde ich mich hier garantiert nochmal zu wort^^ entweder mit positiven oder negativen neuigkeiten^^ euch schonmal einen schönen abend!
Gast
#3019802
Dann freue ich mich schon auf die nächste Fehlermeldung: "Ich habe in C# die Variable 400 programmiert und bekomme dieses Textfeld nicht im µC verarbeitet." |^)
Bronco schrieb: > "Ich habe in C# die Variable 400 programmiert und bekomme dieses > Textfeld nicht im µC verarbeitet." > |^) :-) > > also schließe ich aus dem letzten beitrag das es vll sinnvoller ist das > ganze in sogenannten "Strings" zu übergeben?! Vor allen Dingen das 'sogenannte' macht mir jetzt schon Kummer. Das verspricht wieder mal für die Zukunft die Aufforderung "Kauf dir ein C-Buch" einsetzen zu müssen.
Gast
#3019835
Du kannst es dir sogar noch ein wenig einfacher machen in dem du definierst, dass alle Anweisungen eine feste Länge haben. Um bei dem Beispiel von Karl Heinz Buchegger zu bleiben: Jeder Code hat 4 Zeichen gefollgt von einem Terminator (;) dann wären das z.B.: A649; (Füllstand 1 = 649) B098; (Füllstand 2 = 98) C???; (Abfrage Füllstand 3) (Antwort könnte dann z.B. F193; sein) Auf diese weise kannst du dann auch rellativ einfach ungültige Codes erkennen und verwerfen.
Sascha schrieb: > Du kannst es dir sogar noch ein wenig einfacher machen in dem du > definierst, dass alle Anweisungen eine feste Länge haben. Kann man machen, ist aber nicht so schlimm. atoi ist da sehr brauchbar einzusetzen (wenn man Übertragungsfehler erst mal ignorieren kann) if( isalpha( Input[0] ) ) // Abfrage eines Wertes if( Input[1] == '?' ) { char Answer[10]; switch( Input[0] ) { case 'A': sprintf( Answer, "A%d;", (int)Fuellstand1 ); break; case 'B': .... } } // Neu setzen eines Wertes else { int Wert = atoi( &Input[1] ); switch( Input[0] ) { case 'A': Fuellstand1 = Wert; break; case 'B': ..... } } } Wenn er erst mal den String sauber hat, ist die Auswertung bei nur 3 möglichen Werten nicht mehr so wild und sollte ihn eigentlich vor keine großen Probleme stellen. Aber erst mal muss er den String sauber haben :-)
Sooooo liebe leute... Pünktlich zur nächsten Fehlermeldung meldet sich der junior wieder... mit meinem C-Programm im Controller bin ich eigendlich ganz zufrieden. (Die ansteuerung der LED´s ist lediglich zum Test, hat also nicht viel sinn!) Mein Problem liegt nun in dem Part : private void button1_Click(object sender, EventArgs e) { serialPort1.Open(); char[] wert = new Char[3]; wert[0] = Convert.ToChar(numericUpDown1.Value/4); wert[1] = Convert.ToChar(numericUpDown2.Value/4); wert[2] = Convert.ToChar(numericUpDown3.Value/4); serialPort1.Write(wert, 0, 3); } auf drängen meines Betreuungslehrers habe ich das ganze einfach versucht in arrays zu packen und dann zu übertragen, statt wie von euch vorgeschlagen Strings zu nutzen... nun zeigt mir mein Visual Studio aber die Convertierung der "NumericUpDown" Schaltfläsche als fehlerhaft an... habe ich da irgendwo nen dicken Bock drin!?
NumericUpDown.Value ist vom Typ decimal Convert.ToChar gibt es zwar in einer passenden Variante, die aber nur InvalidCastException auslöst (ebenso wie ein cast von decimal nach char). D.h. vorher in was passendes umwandeln oder casten. Weiteres mögliches "Problem": Char ist 16-Bit Unicode, die Methoden der SerialPort-Klasse konvertieren beim Senden/Empfangen zwar, aber voreingestellt nach/von ASCII d.h. alles >127 kommt nicht richtig an. Da müsste dann u.U. einmal nach dem Erzeugen mit serialPort.Encoding = System.Text.Encoding.GetEncoding(1252); (Windows Codepage 1252) oder serialPort.Encoding = System.Text.Encoding.GetEncoding(28591); (ISO 8859-1) die Voreinstellung geändert werden, damit das nicht passiert. p.s. da ist noch ein Problem die "4" ist ein int, die decimal-Konstante hat noch ein "m" am Ende -> "4m" oder "4.0m"
das /4 soll den eingegebenen Wert von ml in Bits umwandeln, da ich laut Auflösung 4ml jeh Bit genauigkeit habe... soll also nicht übertragen werden
Tobias Giesen schrieb: > das /4 soll den eingegebenen Wert von ml in Bits umwandeln, da ich laut > Auflösung 4ml jeh Bit genauigkeit habe... soll also nicht übertragen > werden Ja, hatte mich da auch vertan integer werden automatisch in decimal umgewandelt. Das Problem mit Convert.ToChar besteht aber weiterhin.
Tobias Giesen schrieb: > das /4 soll den eingegebenen Wert von ml in Bits umwandeln, da ich laut > Auflösung 4ml jeh Bit genauigkeit habe... soll also nicht übertragen > werden Das ist erst mal ziemlich egal. Denn die Convert.ToChar Methode macht das Problem und nicht worauf du es anwendest. Den Datentyp Char musst du auf dem PC vermeiden. Das ist nicht derselbe 'Character', den du vom AVR kennst. Auf dem PC sind die Dinge ein wenig komplizierter, weil deine Programme auch auf Einzelcharacter-Ebene auch mit chinesischen Schriftzeichen klar kommen müssen - sprich: da ist Unicode ein Thema, welches du auf einem AVR nicht hast. Auf dem PC wird wohl eher der Datentyp byte angebracht sein. Der entspricht noch am ehesten dem, was du auf dem AVR als char kennst. > auf drängen meines Betreuungslehrers habe ich das ganze einfach > versucht in arrays zu packen und dann zu übertragen, statt wie > von euch vorgeschlagen Strings zu nutzen... Einen schönen Gruß von uns. Gleich danach stellst du dein PC-Programm auf Dauersenden mit wechselnden Werten um, ziehst das USART-Kabel ab, steckst es wieder ein und erfreust dich daran, dass dein AVR unsinnige Kommandos ausführt. Und dann fragst du ihn mal scheinheilig, ob ein Protokoll vielleicht doch keine so schlechte Idee gewesen wäre.
jep... und da hab ich erlich gesagt null ahnung... ok also ich kann den
decimal nicht direkt in char umwandeln...
wie und in was wandel ich das ganze denn am besten?!
und der Punkt mit der übertragung >127...
muss ich dann einfach
private void button1_Click(object sender, EventArgs e)
{
serialPort1.Open();
char[] wert = new Char[3];
wert[0] = Convert.ToChar(numericUpDown1.Value/4);
wert[1] = Convert.ToChar(numericUpDown2.Value/4);
wert[2] = Convert.ToChar(numericUpDown3.Value/4);
serialPort1.Write(wert, 0, 3);
serialPort.Encoding =
System.Text.Encoding.GetEncoding(28591);
}
schreiben!?
> > Einen schönen Gruß von uns. > Gleich danach stellst du dein PC-Programm auf Dauersenden mit > wechselnden Werten um, ziehst das USART-Kabel ab, steckst es wieder ein > und erfreust dich daran, dass dein AVR unsinnige Kommandos ausführt. Und > dann fragst du ihn mal scheinheilig, ob ein Protokoll vielleicht doch > keine so schlechte Idee gewesen wäre. da wird er sich freuen :D
Tobias Giesen schrieb: > > da wird er sich freuen :D Das liegt in der Natur der Sache. :-) Im Ernst. Wenn man nur 1 Messwert hat (also bei dir nur 1 Füllstand), bestehend aus 1 Byte, dann kann man das so machen, dass man ohne Protokoll fährt. Aber für alles andere ist ein Protokoll eine zwingende Voraussetzung. Alles andere ist einfach nur amateuerhafter Murks. Daran ändert auch nichts, dass er es dir jetzt erst mal so einfach wie möglich machen will. Da soll er dir lieber beibringen, wie man in C mit Strings hantiert. Da haben alle mehr davon und so schwer ist das dann auch wieder nicht.
Tobias Giesen schrieb: > private void button1_Click(object sender, EventArgs e) > { > ... > serialPort1.Write(wert, 0, 3); > serialPort.Encoding = > System.Text.Encoding.GetEncoding(28591); > } > > > schreiben!? An der Stelle ist es für das erste Senden zu spät, am einfachsten ist es das bspw. im Konstruktor der Form zu machen.
1 | |
2 | |
3 | |
4 | |
ok... ich merk schon ihr seid echte fans meines Lehrers :D
leider werde ichs wohl (ob nun gut oder schlecht) so machen müssen wie
er es vorgibt :(
ok... also sollte ich die sache vll in Byte schreiben!?
private void button1_Click(object sender, EventArgs e)
{
serialPort1.Open();
Byte[] wert = new Byte[3];
wert[0] = Convert.ToByte(numericUpDown1.Value/4);
wert[1] = Convert.ToByte(numericUpDown2.Value/4);
wert[2] = Convert.ToByte(numericUpDown3.Value/4);
serialPort1.Write(wert, 0, 3);
}
?!
Tobias Giesen schrieb: > ok... also sollte ich die sache vll in Byte schreiben!? Ich würde sagen: Ja. Denn letzten Endes sind es ja eigentlich auch nur Bytes ohne spezielle Bedeutung (im Gegensatz zu Strings), die da über die Serielle rauschen.
Soo.. Im grundsatz funktioniert alles^^ Jedoch muss ich beim senden über c# immer mehrmals auf den "mischen" button zum senden klicken, damitich werte im controller empfange... Jemand ne idee!?
Tobias Giesen schrieb: > Soo.. Im grundsatz funktioniert alles^^ > Jedoch muss ich beim senden über c# immer mehrmals auf den "mischen" > button zum senden klicken, damitich werte im controller empfange... > Jemand ne idee!? Wie immer: Als erstes mal feststellen auf welcher Seite das 'Problem' liegt. Sender oder Empfänger Ein einfacher Weg ist zb die INstallation eines Port Sniffers auf dem PC. Damit siehst du alle Bytes, so wie sie über die Serielle gehen. Wenn bei Klicken auf einen Button dort auch was auftaucht, dann wird wohl der Empfänger die Bytes verschludern. Wenn nicht .... Danach weiß man schon mal, worauf man sich konzentrieren muss. Der erste Schritt im Bugfixing ist IMMER die Einkreisung des Problems auf den relevanten Teil. In deinem Fall ist das erst mal die Frage: Sender oder Empfänger?
Haste nen tipp für einen solchen sniffer?!
http://www.serialmon.com/ google "pc serial port sniffer"
Antwort schreiben
Bitte melde dich an, um einen Beitrag zu schreiben.


