Forum: Mikrocontroller und Digitale Elektronik Master und 3 Slaves, Kommunikation läuft nicht rund Bitte um Hilfe


von Chris T. (chris0086)


Angehängte Dateien:

Lesenswert?

Hallo Leute,
ich verzweifel gerade an der Kommunikation mit einem Master und aktuell 
2 Slaves.
Die Controller sind Atmega 32 und per RS485 miteinander verbunden.
Die Kommunikation läuft zum Anfang doch irgendwann kommen die Slaves mit 
der Empfangsroutine durcheinander und senden dann nichtmehr zurück weil 
in der Empfangsroutine wohl der Index nichtmehr stimmt.
Wie mach ich das richtig damit die nichtmehr aus dem Tritt kommen?
Hier erstmal der Mastercode:


Der Master sendet mit sendrequest = 
Master_send_command(current_controller,48,0);
eine Anfragenachricht an die Slaves, das sind 8 bis 9 byte.

Wenn dann die antwort vom Slave empfangen wurde wird  if(u_r_c != 0) 
//Gerät hat geantwortet
ungleich 0 und die Antwort wird ausgewertet.

So der Code vom Slave ist bisher etwas kürzer:




Die Sendeund Empfangsroutinen sehen gleich aus aber irgendwie passen 
irgendwann die Indexe nichtmehr auf die der Controller schuat und 
vergleicht.
Wie kann ich das besser machen?

Die slaves sollen später auch noch was anderes machen als nur 
NAchrichten beantworten aber wenns dadran schon hapert komm ich nicht 
weiter.

Bitte um Hilfe, es sind immer nur zwei unterschiedliche Telegrammtypen 
die gesendet werden also eigentlich nix schweres.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Welchen Teil von Längeren Sourcecode nicht im Text einfügen, *sondern 
als Dateianhang* hast Du jetzt nicht verstanden?

Wenn Du das als *.c anhängst, bietet die Forensoftware sogar einen 
Dateibetrachter mit Zeilennummern ...

von STK500-Besitzer (Gast)


Lesenswert?

Bau beim Slave ein Timeout ein, woraufhin er die 
Kommunikationsgeschichte auf Start zurücksetzt.

von Wolfgang (Gast)


Lesenswert?

Chris T. schrieb:
> Wie mach ich das richtig damit die nichtmehr aus dem Tritt kommen?

Überlege dir, woran merkst du, dass die aus dem Tritt kommen. Bringe das 
der Software bei und triggere damit einen Logikanalysator. Im Pretrigger 
kannst du dann gucken, was vorher auf dem Bus passiert ist, so dass du 
dir überlegen kannst, warum das passiert ist.

Falls es durch Störsignale passiert (damit solltest du immer rechnen) 
und nicht durch einen Software-/Algorithmenfehler passiert, überlege 
dir, wie du die Synchronität wieder herstellen kannst.

Und nein - durch 18 Seiten Quelltext, von dem ich nicht die geringste 
Ahnung habe, was da passieren soll, turne ich jetzt nicht durch ;-)

von Chris T. (chris0086)


Lesenswert?

Rufus Τ. F. schrieb:
> Welchen Teil von Längeren Sourcecode nicht im Text einfügen, *sondern
> als Dateianhang* hast Du jetzt nicht verstanden?

Tut mir Leid da habe ich nicht dran gedacht, habs mal schnell geändert.
Hier nochmal der wie ich denke wichtige Code:
Empfangsroutine:
1
ISR(USART_RXC_vect)
2
{
3
  
4
  
5
  uint8_t i;
6
  if(uart_transmit_progress)
7
  {
8
    uart_r_array[u_rx_start] = UDR;
9
    uart_back_read=1;
10
  }
11
  else
12
  {
13
    i = u_rx_start;
14
    u_receive_string[i] = UDR;
15
    //lcd_putc(i);
16
    // Sendstring: 01 10 01 00 01 04 00 00 30 18
17
    if (i==5)
18
        {
19
          receive_max = u_receive_string[i] +5;
20
        }
21
22
    if(i == receive_max)
23
    {
24
      u_rx_start=0;
25
      
26
      u_r_c = receive_max;
27
      //USART_Transmit('Z');
28
29
    }
30
    else
31
    {
32
33
      i++;
34
      u_rx_start = i;
35
    }
36
  }
37
}

Und hier dann die Main:
1
while(1)
2
  {
3
    if(u_r_c != 0) //Es wurden Daten empfangen
4
    {
5
      systic = 0;
6
      //Farbe setzen:        01 11 01 00 01 04 01 FF 00 00
7
      //Sensorwerte abfragen:    01 30 01 00 01 00
8
      uint8_t funktion;
9
      uint8_t feld;
10
      //36 = Feld2 controller 4
11
      funktion = (u_receive_string[1]>>4);
12
      feld = (u_receive_string[1] &= 0x0F);
13
      if (funktion == 1)      //Farbe setzen
14
      {
15
        LED2_C;
16
        switch_color(u_receive_string[7],u_receive_string[8],u_receive_string[9],u_receive_string[6]);
17
        
18
      }
19
      else                //Sensorwerte abfragen request
20
      {
21
        Slave_send_command(SLAVEADRESS,48,1,0025);
22
        LED3_C;
23
      }
24
      u_rx_start=0;
25
26
27
      //uart_putc((uint8_t) u_r_c);
28
      u_r_c = 0;
29
      
30
    }
31
    if((systic >=10) && (u_rx_start ==0))
32
    {
33
      systic = 0;
34
      u_rx_start=0;
35
    }
36
    
37
  }

von Chris T. (chris0086)


Lesenswert?

Theoretisch sollte die Empfangsroutine für sich selbst laufen, nur wenn 
die aktuelle Nachricht für den Slave mit der passenden Adresse ist wird 
ans hauptprogramm gemeldet das etwas angekommen ist.
anschließend fängt die Routine wieder von vorne an das Array zu 
beschreiben, leider kommt die ganze Sache irgendwann ausdem Tritt...

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Chris T. schrieb:
> Tut mir Leid da habe ich nicht dran gedacht, habs mal schnell geändert.

Gut!

von Chris T. (chris0086)


Lesenswert?

Hat jemand Ansatzpunkte für mich?
Was mich auch irritiert, meine controller laufen alle mit internem Takt 
von 8Mhz, ich habe bei den slaves einen Timer laufen und bei jedem 
Compare match wird die LED ein/aus geschaltet, die BLinkreihenfolge 
weicht aber nach ein paar sekunden ab. ist das für den Empfang schlimm 
oder gleicht der Hardwareuart das aus?


EDIT: ich hab jetzt überall einen 7,372800Mhz Quarz dran.

von Chris T. (chris0086)


Lesenswert?

Okay das Grundproblem war wirklich die ungenaue Taktrate alle µC.

Jetzt wo überall ein Quarz drin ist läuft es seit einer Stunde im 
Dauerbetrieb durch.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.