Datum:
mal eine kurze frage zum Empfang auf der oder die UART, ich sende vom slave seine adresse zum Master wie volgt: Slave sendet; uart_putc(40); Master empfang: i=0; while ( ( c2 = uart1_getc() ) != 0x28 && i < Len2 - 1 ) in[ i++ ] = c2; in[i] = '\0'; muss ich in der While != 0x28 das so abfragen oder While == 40 mfg
Datum:
ingo schrieb: > muss ich in der While != 0x28 das so abfragen oder While == 40 > mfg Die Zahlendarstellung ist egal. Was soll die While-Schleife machen? Soll sie solange durchlaufen werden, bis 40 gesendet wurde und die Daten bis dahin ins Array geschrieben werden? Oder soll sie solange warten, bis nicht mehr 40 empfangen wird? Ich vermute das erste. Dann ist die Schreibweise richtig.
Datum:
> ingo schrieb: > Die Zahlendarstellung ist egal. > Was soll die While-Schleife machen? > Soll sie solange durchlaufen werden, bis 40 gesendet wurde und die Daten > bis dahin ins Array geschrieben werden? ja genau also währe es so auch richtig, while ( ( c2 = uart1_getc() ) == 40 && i < Len2 - 1 ) in[ i++ ] = c2; in[i] = '\0'; ich habe 2 Slave jeweils adresse 40 und 41, wenn ich die slaves nacheinander anspreche zB. uart_putc(40); while ( ( c2 = uart1_getc() ) == 40 && i < Len2 - 1 ) in[ i++ ] = c2; in[i] = '\0'; ..... Ausgabe auf mein lcd uart_putc(41); while ( ( c2 = uart1_getc() ) == 41 && i < Len2 - 1 ) in[ i++ ] = c2; in[i] = '\0'; ..... Ausgabe auf mein lcd bekomme ich nur die daten von adresse 41 angezeigt. spreche ich die svlaves nur einzeln an gehts.
Datum:
ingo schrieb: > also währe es so auch richtig, > while ( ( c2 = uart1_getc() ) == 40 && i < Len2 - 1 ) > in[ i++ ] = c2; > in[i] = '\0'; Nein. es muss "!= 40" heissen. ingo schrieb: > bekomme ich nur die daten von adresse 41 angezeigt. > > spreche ich die svlaves nur einzeln an gehts. Dann hast du wohl einen Fehler im Programm...
Datum:
Hallo, ich bekomme den Fehler nicht weg.
//MASTER //################################################################################### void get_show_all (uint8_t s) //Hole Daten von Modul 1 ubd 2 //################################################################################### { char Buff1_V[20]; char Buff1_A[20]; char Buff1_W[20]; char Buff2_V[20]; char Buff2_A[20]; char Buff2_W[20]; int c1; int i = 0; int Len1 = 32; char inLine[32]; uint8_t v1,v2; uint8_t a1,a2; uint8_t w1,w2; unsigned int spannung; unsigned int strom; unsigned int watt; unsigned int adcval; if ( s == 1 ) { //Modul 1 //################################################################################### setTransmitMode(); rgbsend_data(0xA4); // rgbsend_data(40); //Adresse zum Modul 1 senden setReceiveMode(); //################################################################################### i=0; while ( ( c1 = uart1_getc() ) != 40 && i < Len - 1 ) { inLine[ i++ ] = c1; } inLine[i] = '\0'; v1=inLine1[0]; v2=inLine1[1]; a1=inLine1[0]; a2=inLine1[1]; w1=inLine1[0]; w2=inLine1[1]; adcval1= v1 * 256 + v2; spannung1 = ((long)adcval1 * 5000) / 1023; // A/D-Wert in Spannung umrechnen (AREF=5V, 10 Bit A/D-Wandler: sprintf( Buff1_V, "V: %1d.%02d ", spannung1/ 1000, spannung1 % 1000 ); adcval1= a1 * 256 + a2; strom1 = ((long)adcval1 * 3000) / 1023; // A/D-Wert in Strom umrechnen (AREF=5V, 10 Bit A/D-Wandler: sprintf( Buff1_A, "A: %1d.%02d ", strom1/ 1000, strom1 % 1000 ); adcval1= w1 * 256 + w2; watt1 = ((long)adcval1 * 36000) / 1023; // A/D-Wert in Watt umrechnen (AREF=5V, 10 Bit A/D-Wandler: sprintf( Buff1_W, "W: %1d.%02d ", watt1/ 1000, watt1 % 1000 ); //GLCD_FONT Einstellen setfont(Font4); gotoxy(3,252 ); uart_putc (' '); uart_puts (Buff1_A); gotoxy(3,316 ); uart_putc (' '); uart_puts (Buff1_V); gotoxy(3,376 ); uart_putc (' '); uart_puts (Buff1_W); } if ( s == 2 ) { //Modul 2 //################################################################################### setTransmitMode(); rgbsend_data(0xA4); // rgbsend_data(41); //Adresse zum Modul 2 senden setReceiveMode(); //################################################################################### i=0; while ( ( c1 = uart1_getc() ) != 41 && i < Len - 1 ) { inLine[ i++ ] = c1; } inLine[i] = '\0'; v1=inLine1[0]; v2=inLine1[1]; a1=inLine1[0]; a2=inLine1[1]; w1=inLine1[0]; w2=inLine1[1]; adcval2= v1 * 256 + v2; //adcval = atoi( &inLine2[0] ); spannung2 = ((long)adcval2 * 5000) / 1023; // A/D-Wert in Spannung umrechnen (AREF=5V, 10 Bit A/D-Wandler: sprintf( Buff2_V, "V: %1d.%02d ", spannung2/ 1000, spannung2 % 1000 ); adcval2= v1 * 256 + v2;//v1 * 256 + v2;//a1 * 256 + a2; strom2 = ((long)adcval2 * 3000) / 1023; // A/D-Wert in Strom umrechnen (AREF=5V, 10 Bit A/D-Wandler: sprintf( Buff2_A, "A: %1d.%02d ", strom2/ 1000, strom2 % 1000 ); adcval2= v1 * 256 + v2;//w1 * 256 + w2; watt2 = ((long)adcval2 * 36000) / 1023;// A/D-Wert in Watt umrechnen (AREF=5V, 10 Bit A/D-Wandler: sprintf( Buff2_W, "W: %1d.%02d ", watt2/ 1000, watt2 % 1000 ); //GLCD_FONT Einstellen setfont(Font4); gotoxy(171,252 ); uart_putc (' '); uart_puts (Buff2_A); gotoxy(171,316 ); uart_putc (' '); uart_puts (Buff2_V); gotoxy(171,376 ); uart_putc (' '); uart_puts (Buff2_W); } } //SLAVE_1 for (;;) { c = uart_getc(); //Hole Daten vom UART ab if (c==0xA4) // { c1=uart_getc(); if (c1==41) // Stimt die Geräte adresse { adcval = ADC_Read_Avg(0, 4); // Kanal 0, Mittelwert aus 4 Messungen setTransmitMode(); uart_putc(*((char*)&adcval+1)); //High-Byte? uart_putc(*((char*)&adcval)); //Low-Byte uart_putc(40); setReceiveMode(); } } } } //SLAVE_1 for (;;) { c = uart_getc(); //Hole Daten vom UART ab if (c==0xA4) // { c1=uart_getc(); if (c1==41) // Stimt die Geräte adresse { adcval = ADC_Read_Avg(0, 4); // Kanal 0, Mittelwert aus 4 Messungen setTransmitMode(); uart_putc(*((char*)&adcval+1)); //High-Byte? uart_putc(*((char*)&adcval)); //Low-Byte uart_putc(41); setReceiveMode(); } } } } |
Datum:
> > > > >//SLAVE_1 > for (;;) > { > c = uart_getc(); //Hole Daten vom UART ab > > > if (c==0xA4) // > { > c1=uart_getc(); > if (c1==41) // Stimt die Geräte adresse > Hier sollte es wohl 40 heissen und nicht 41! > { > adcval = ADC_Read_Avg(0, 4); // Kanal 0, Mittelwert aus 4 Messungen > setTransmitMode(); > > uart_putc(*((char*)&adcval+1)); //High-Byte? > uart_putc(*((char*)&adcval)); //Low-Byte > > uart_putc(40); > setReceiveMode(); > } > } > } >} tu dir selbst einen Gefallen und modularisiere deinen Code ein wenig. So Dinge wie zb die Slave Adressen gehören nicht im Code versteckt, sondern werden zentral an EINER Stelle mit einem #define vereinbart #define SLAVE_1_ADDR 40 ... c1 = uart_getc(); if (c1 == SLAVE_1_ADDR ) // Stimt die Geräte adresse .... uart_putc( SLAVE_1_ADDR ); Dann hast du die Sicherheit, dass die beiden Zahlen auf jeden Fall zusammenstimmen! Derartige 'magische Zahlen' gehören nicht in den Code. Das ist viel zu fehleranfällig, dass man bei einer Änderung eine Stelle übersieht. Mit einem #define kann dir aber genau dieses Versehen nicht passieren. Du änderst an EINER Stelle die 40 zur 41 (eben beim #define) und der Compiler sorgt dafür, dass diese Änderung überall durchgezogen wird. Und der macht dabei keine Fehler. Genauso dein Master-Code: Das ist im Prinzip immer die gleiche FUnktionalität! Mach dir EINE Funktion, die das Prozedere der Datenübertragung abhandelt und der übergibst du die gewünschte Slave-Adresse. Es gibt keinen Grund, das ganze per Copy&Paste zu lösen. Du läufst wieder nur Gefahr, dass du die beiden Slaves unterschiedlich behandelst, weil du in einem Codeteil einen Bugfix machst und im anderen vergisst du ihn. Codeorganisation ist ein wesentlicher und vitaler Bestandteil, um möglichst fehlerfreien Code zu produzieren. Dazu gehören zb auch eigene Ausgabefunktionen, in denen du gleichartige Funktionalität zusammenfassen kannst. Deine get_show_all könnte zb so aussehen
#define SLAVE_1_ADDR 40 #define SLAVE_2_ADDR 41 void get_show_all (uint8_t s) { uint16_t Volt = 0, Ampere = 0, Watt = 0; uint8_t OutputColumn = 3; if( s == 1 ) { GetValues( SLAVE_1_ADDR, &Volt, &Ampere, &Watt ); OutputColumn = 3; } else if( s == 2 ) { GetValues( SLAVE_2_ADDR, &Volt, &Ampere, &Watt ); OutputColumn = 171; } ShowValue( OutputColumn, 252, "A: %1d.%02d", Ampere ); ShowValue( OutputColumn, 316, "V: %1d.%02d", Volt ); ShowValue( OutputColumn, 376, "W: %1d.%02d", Watt ); } |
Siehst du um wieviel einfacher es hier ist, den Programmfluss zu verfolgen und nachzuvollziehen, was an welcher Stelle ausgegeben wird? Und das alles für den 'Preis' von ein paar (trivialen) Spezialfunktionen, die jeweils einen Teilaspekt der kompletten Arbeit erledigen.
Datum:
ps "W: %1d.%02d ", watt2/ 1000, watt2 % 1000 ); Tausendstel und %02d passen nicht zusammen. Für Tausendstel brauchst du 3 "Nachkommastellen". Mit "%1d.%02d" wird eine Zahl 1005 bei dir als 1.05 ausgegeben. Die korrekte Anzeige wäre aber 1.005 und das ist dann schon ein gewisser Unterschied.
Datum:
>Tausendstel und %02d passen nicht zusammen. Für Tausendstel brauchst du >3 "Nachkommastellen". ja stimmt ich hab das vielzu umständlich, aber mein problem ist ich sende zum slave1 0xA4,40 zeige die empfangenen daten an,dann slave2 0xA4,41 , bekomm ich an erster Augabestelle immer die daten von slave2. spreche ich nur slave1 oder slave2 an dann gehts. die slaves sollen dann den internen ADC auslesen und zum Master senden der adc läuft im 10bit mode.
Datum:
ingo schrieb: >>Tausendstel und %02d passen nicht zusammen. Für Tausendstel brauchst du >>3 "Nachkommastellen". > > ja stimmt ich hab das vielzu umständlich, Tja. Dein Problem wird eher genau hier liegen. Dadurch das das alles viel zu umständlich ist, siehst du den eigentlichen Fehler vor lauter umständlich nicht mehr. > aber mein problem ist ich sende zum slave1 0xA4,40 zeige die empfangenen > daten an,dann slave2 0xA4,41 , > bekomm ich an erster Augabestelle immer die daten von slave2. > > spreche ich nur slave1 oder slave2 an dann gehts. Was heißt nur? Deine Funktion kann sowieso immer nur entweder den einen oder den anderen Slave ansprechen. Hast du kontrolliert, ob du get_show_all auch tatsächlich abwechselnd mit 1 oder 2 aufrufst? (Trotzdem solltest du die Funktion vereinfachen. Massiv vereinfachen. Mann kann sich auch in der selbst geschaffenen Komplexität verirren)
Datum:
get_show_all wird abwechslnd aufgerufen
get_show_all (1);
Delay1ms(100);
get_show_all (2);
aber meinproblem bleibt halt der empfang der daten auf dem master,
i=0;
while ( ( c1 = uart1_getc() ) != SLAVE_1_ADDR && i < Len - 1 )
{
inLine[ i++ ] = c1;
}
inLine[i] = '\0';
v1=inLine[0];
v2=inLine[1];
a1=inLine[0];
a2=inLine[1];
w1=inLine[0];
w2=inLine[1];
adcval= v1 * 256 + v2;
spannung = ((long)adcval * 5000) / 1023; // A/D-Wert in Spannung
umrechnen (AREF=5V, 10 Bit A/D-Wandler:
sprintf( Buff1_V, "V: %1d.%02d ", spannung/ 100, spannung % 100 );
adcval= a1 * 256 + a2;
strom = ((long)adcval * 3000) / 1023; // A/D-Wert in Strom umrechnen
(AREF=5V, 10 Bit A/D-Wandler:
sprintf( Buff1_A, "A: %1d.%02d ", strom/ 100, strom % 100 );
adcval= w1 * 256 + w2;
watt = ((long)adcval * 36000) / 1023; // A/D-Wert in Watt
umrechnen (AREF=5V, 10 Bit A/D-Wandler:
sprintf( Buff1_W, "W: %1d.%02d ", watt/ 100, watt % 100 );
Datum:
ingo schrieb: > get_show_all wird abwechslnd aufgerufen > > get_show_all (1); > Delay1ms(100); > get_show_all (2); > > > aber meinproblem bleibt halt der empfang der daten auf dem master, Aus dem was du gepostet hast, kann ich nur den Schluss ziehen, das du einen riesen Durcheinander auf der UART veranstaltest, weil dein einer Slave auf die falsche Adresse reagiert. Du suchst an der falschen Stelle und dein unübersichtlicher Code tut sein übriges. Sorry. Aber genau so sieht die Sache aus.
Datum:
ich sende doch die slave adresse zb40 der slave sendet seine daten mit seiner adresse, gut ich geb zu bei mir ist dies sehr umständlich vom code her. aber wie krieg ich denn nun die werte in Volt, Ampere, Watt ; vielleicht könnten sie mir da noch ein wenig weiterhelfen.
#define SLAVE_1_ADDR 40 #define SLAVE_2_ADDR 41 void get_show_all (uint8_t s) { uint16_t Volt = 0, Ampere = 0, Watt = 0; uint8_t OutputColumn = 3; if( s == 1 ) { GetValues( SLAVE_1_ADDR, &Volt, &Ampere, &Watt ); OutputColumn = 3; } else if( s == 2 ) { GetValues( SLAVE_2_ADDR, &Volt, &Ampere, &Watt ); OutputColumn = 171; } ShowValue( OutputColumn, 252, "A: %1d.%02d", Ampere ); ShowValue( OutputColumn, 316, "V: %1d.%02d", Volt ); ShowValue( OutputColumn, 376, "W: %1d.%02d", Watt ); } GetValues( SLAVE_1_ADDR, &Volt, &Ampere, &Watt ) { char Buff1_V[20]; char Buff1_A[20]; char Buff1_W[20]; char inLine[32]; int c1; int i = 0; int Len = 32; uint8_t v1,v2; uint8_t a1,a2; uint8_t w1,w2; unsigned int spannung; unsigned int strom; unsigned int watt; unsigned int adcval; setTransmitMode(); rgbsend_data(0xA4); //Adresse zum Modul 2 senden rgbsend_data(SLAVE_1_ADDR); // setReceiveMode(); i=0; while ( ( c1 = uart1_getc() ) != SLAVE_1_ADDR && i < Len - 1 ) { inLine[ i++ ] = c1; } inLine[i] = '\0'; v1=inLine[0]; v2=inLine[1]; a1=inLine[0]; a2=inLine[1]; w1=inLine[0]; w2=inLine[1]; adcval= v1 * 256 + v2; spannung = ((long)adcval * 5000) / 1023; // A/D-Wert in Spannung umrechnen (AREF=5V, 10 Bit A/D-Wandler: sprintf( Buff1_V, "V: %1d.%02d ", spannung/ 100, spannung % 100 ); adcval= a1 * 256 + a2; strom = ((long)adcval * 3000) / 1023; // A/D-Wert in Strom umrechnen (AREF=5V, 10 Bit A/D-Wandler: sprintf( Buff1_A, "A: %1d.%02d ", strom/ 100, strom % 100 ); adcval= w1 * 256 + w2; watt = ((long)adcval * 36000) / 1023; // A/D-Wert in Watt umrechnen (AREF=5V, 10 Bit A/D-Wandler: sprintf( Buff1_W, "W: %1d.%02d ", watt/ 100, watt % 100 ); //GLCD_FONT Einstellen setfont(Font4); gotoxy(3,252 ); uart_putc (' '); uart_puts (Buff1_A); gotoxy(3,316 ); uart_putc (' '); uart_puts (Buff1_V); gotoxy(3,376 ); uart_putc (' '); uart_puts (Buff1_W); } |
Datum:
ingo schrieb: > ich sende doch die slave adresse zb40 der slave sendet seine daten mit > seiner adresse, Dann sieh dir (noch-)mal den von dir geposteten Code für Slave 1 an
//SLAVE_1 for (;;) { c = uart_getc(); //Hole Daten vom UART ab if (c==0xA4) // { c1=uart_getc(); if (c1==41) // Stimt die Geräte adresse { adcval = ADC_Read_Avg(0, 4); // Kanal 0, Mittelwert aus 4 Messungen setTransmitMode(); uart_putc(*((char*)&adcval+1)); //High-Byte? uart_putc(*((char*)&adcval)); //Low-Byte uart_putc(40); setReceiveMode(); } } } } |
Der Slave reagiert auf den Erhalt von 41 und sendet 40 zurück. (Und wenn der Messwert zufällig auch noch so ist, dass das Lowbyte als 40 gelesen werden kann, dann kommt sowieso alles durcheinander)
Datum:
> GetValues( SLAVE_1_ADDR, &Volt, &Ampere, &Watt )
so beginnt aber keine Funktion!
Du brauchst dringend ein C-Buch. Da fehlt es an den Grundlagen
void GetValues( uint8_t SlaveAddr, uint16_t *Volt, uint16_t *Ampere, uint16_t *Watt ) { uint8_t inLine[32]; uint8_t c, i; setTransmitMode(); rgbsend_data(0xA4); // Startkommando: Messen rgbsend_data(SlaveAddr); // Adresse schicken setReceiveMode(); i = 0; while( ( c = uart1_getc() ) != SlaveAddr && i < sizeof(inLine) ) { inLine[ i++ ] = c; } if( i >= 2 ) // genug Bytes bekommen? { *Volt = inLine[0] * 256U + inLine[1]; *Ampere = inLine[0] * 256U + inLine[1]; *Watt = inLine[0] * 256U + inLine[1]; } else { *Volt = 9999; *Ampere = 9999; *Watt = 9999; } } |
Datum:
eine Frage habe ich noch; der Aufruf ShowValue( OutputColumn, 252, "A: %1d.%02d", Ampere ); das hier "A: %1d.%02d" da weis ich nicht wie ich mir eine funktion schreiben muss. Leider gibst beim compelieren einen Fehler in der zeile void ShowValue( OutputColumn, 252, s ,uint16_t wert ) before numeric constant
//Prototyp //void ShowValue(int Column, int y, const char *s, uint16_t wert); void ShowValue( OutputColumn, 252, s ,uint16_t wert ) { char Buff1_V[20]; char Buff1_A[20]; char Buff1_W[20]; wert = ((long)wert * 36000) / 1023; // A/D-Wert in Watt umrechnen (AREF=5V, 10 Bit A/D-Wandler: sprintf( Buff1_W, s, wert/ 100, wert % 100 ); //GLCD_FONT Einstellen setfont(Font4); gotoxy( OutputColumn, 252); uart_putc (' '); uart_puts (Buff1_A); } |
Datum:
ingo schrieb: > //Prototyp > //void ShowValue(int Column, int y, const char *s, uint16_t wert); > > void ShowValue( OutputColumn, 252, s ,uint16_t wert ) > { Besorg Dir ein C-Buch. Und lies das durch. Dir hier mit Tips weiterzuhelfen ist bei Deinem eklatanten Mangel an Grundlagenwissen vollkommen sinnlos. Auch das Durchklicken durch irgendwelche C-Tutorials dürfte Dich nicht wirklich weiterbringen. Empfehlung: Brian Kernighan & Dennis Ritchie, "Programmieren in C", zweite Ausgabe, Hanser-Verlag.