ModBus

Floatberechnung stört ModBus?

Mathias
Benutzer
Avatar
Gender: n/a
Location: Weingarten - Baden
Posts: 310
Registered: 07 / 2003
Subject:

ModBus

 · 
Posted: 14.02.2012 - 05:40  ·  #1
Hallo,

ich vermute, daß die folgenden Floatberechnungen den ModBus stören.
Insoweit, daß die "lange" Rechenzeit irgendwie unverträglich ist.
Auswirkungen sind, manche Daten werden nicht mehr übertragen.
Mega644, 14,7456MHz, Baudr.: . 38400, Compiler Rev: 4.99.00
Testprogramm: ModBus Poll.
Die Berechnungen brauchen jeweils ca. 1,2ms.
Ohne die Formeln läuft alles prima.

Code

{$IDATA}
Var
  fX : Float;
  
  fX:= 50;
  fX:= SQRT(((fX+0.0202)/0.002)+41310.5625)-203.272;
  fX:= 100; 
  fX:= SQRT(fX);
  fX:= 100;
  fX:= (SQRT(-((fX+21.7)/0.001498)+207390)-455.18)*(-1); 
  fX:= 100;
  fX:= (SQRT(((fX+0.0742)/(-0.0014))+165846.7447)-407.2428571)*(-1);
  fX:= 100;
  fX:= SQRT(((fX+0.1204)/0.0019)+45819)-213.87;
  fX:= 100;
  fX:= SQRT(((fX-0.09)/0.0014)+94007.94005)-306.6071429;
  fX:= 100;
  fX:= SQRT(((fX+0.2306)/0.0013)+114686)-337.9;
  fX:= 100;
  fX:= SQRT(((fX-0.99)/0.00007)+49995000)-7070.03;


Könnte ein Forums ModBus-Benutzer den Code in sein Programm übertragen und berichten wie es gelaufen ist?
Wäre nett.

Danke

Gruß
Mathias
pvs-deck
PowerUser
Avatar
Gender:
Age: 53
Homepage: pvs-deck.de
Posts: 1341
Registered: 02 / 2009
Subject:

Re: ModBus

 · 
Posted: 15.02.2012 - 10:05  ·  #2
Quote by Mathias

Hallo,

ich vermute, daß die folgenden Floatberechnungen den ModBus stören.
Insoweit, daß die "lange" Rechenzeit irgendwie unverträglich ist.
Auswirkungen sind, manche Daten werden nicht mehr übertragen.
Mega644, 14,7456MHz, Baudr.: . 38400, Compiler Rev: 4.99.00
Testprogramm: ModBus Poll.
Die Berechnungen brauchen jeweils ca. 1,2ms.
Ohne die Formeln läuft alles prima.

Code

{$IDATA}
Var
  fX : Float;
  
  fX:= 50;
  fX:= SQRT(((fX+0.0202)/0.002)+41310.5625)-203.272;
  fX:= 100; 
  fX:= SQRT(fX);
  fX:= 100;
  fX:= (SQRT(-((fX+21.7)/0.001498)+207390)-455.18)*(-1); 
  fX:= 100;
  fX:= (SQRT(((fX+0.0742)/(-0.0014))+165846.7447)-407.2428571)*(-1);
  fX:= 100;
  fX:= SQRT(((fX+0.1204)/0.0019)+45819)-213.87;
  fX:= 100;
  fX:= SQRT(((fX-0.09)/0.0014)+94007.94005)-306.6071429;
  fX:= 100;
  fX:= SQRT(((fX+0.2306)/0.0013)+114686)-337.9;
  fX:= 100;
  fX:= SQRT(((fX-0.99)/0.00007)+49995000)-7070.03;


Könnte ein Forums ModBus-Benutzer den Code in sein Programm übertragen und berichten wie es gelaufen ist?
Wäre nett.

Danke

Gruß
Mathias

Hallo Mathias,
welche Stack und Framesize hast Du eingestellt?
Rufst Du diese Berechnung zyklisch auf?
Benutzt Du Multitasking?
Wie hoch ist der RxBuffer und TxBuffer vom SerPort?

Ich benutze für meine Modbusgeräte auch 14,7456Mhz (Wegen Baudratenfehler), ich habe verschiedene Berechnungen der ADC-Ports am laufen, Lichtsensor, Temp. und Feuchte.
Ich benutze aber die Baudrate 19.200 oder 57.600.

Ich denke mal eine komplettes Testprogramm wäre hier aber nötig zum testen. Da ich meine Stack- und Framesize sowie die Buffer immer großzügig einstelle (hatte schon oft schlechte Erfahrungen, wenn diese zu klein waren)

Code

...
        StackSize   = $0256, iData;
        FrameSize   = $0256, iData;
...
        SerPort     = 19200, Databit8, Stop1;
        RxBuffer    = 128, iData;
        TxBuffer    = 128, iData;
...


Gruss
Thorsten
Mathias
Benutzer
Avatar
Gender: n/a
Location: Weingarten - Baden
Posts: 310
Registered: 07 / 2003
Subject:

Re: ModBus

 · 
Posted: 16.02.2012 - 06:32  ·  #3
Hallo Thorsten,

Quote
Rufst Du diese Berechnung zyklisch auf?

Genau das war's.
"Für den ModBus wurde zu oft gerechnet".
Habe jetzt einfach einen 20ms Timer vor die Floatberechnung gemacht und siehe da es geht alles!
Der Rechenintervall reicht in diesem Fall aus.

Danke dir.

Gruß
Mathias
Avra
Schreiberling
Avatar
Gender:
Location: Belgrade, Serbia
Age: 53
Homepage: rs.linkedin.com/in…
Posts: 653
Registered: 07 / 2002
Subject:

Re: ModBus

 · 
Posted: 19.02.2012 - 21:02  ·  #4
Although online transaction sucks, I have really tried to understand your problem. If you haven't solved it yet then correct me if I misunderstood something:You didn't say if you use MODBUS RTU or ASCII. Since you seam to want as much speed as you can get I will assume that it is MODBUS RTU. It seams you don't use multitasking, but MODBUS driver does - and RTU version also uses RXRDYx interrupt. You also didn't specify polling interval (scan interval in Modbus Poll software terminology). You didn't specify how many registers are you reading, or how many floating values in each poll, so I will assume that you want to read single float value (which is 2 16-bit registers). You also didn't provide minimal test project, which is essential for such diagnostics.

I have worked with more then a 100 different MODBUS devices in my career, and I have never seen a device being polled more then few times per second. Few MODBUS messages in a polling packet, with hundreds of different registers being read - yes, but single value being read hundreds of times per second - no. If I control both receive and transmit side, I would prefer to just WriteLn() that float to TX and monitor results in some PC terminal software or custom application, instead of overhead and slowdown that some communication protocol introduces. However if receiver is fixed and not under your control (like some MODBUS client like SCADA, PLC or some lab software), then I understand you. In the way you have probably implemented it, many things can go wrong. RX interrupt might happen in the middle of SQRT calculation and corrupt your float result. You might try handshaking and disable interrupt in proper places to fix this. You might also be trying to read faster then possible. For example, with MODBUS request message to read single float (2 registers) in RTU is 8 bytes + 2*(3.5 char times) and in ASCII it is 17 bytes. Reply to this message is in RTU 8 bytes + 2*(3.5 char times) and in ASCII it is 19 bytes. So in it's fastest RTU version, you theoretically need at least 30 character times to get this floating point value from AVR. With 38400 and 10 bits for character this renders to 3840 bytes/sec which is 128 floats/sec, or ~8ms (much higher then 1.2ms). Remember that this is without your AVR application doing other things, without time for drivers (including MODBUS) doing their job, and without other interrupts. Remember that also during all this time for each received character AVR is already in interrupt.

Saying all this, to maximize throughput 1st thing you can try is to set speed as high as possible where you still have 0% baud rate error (115200 or even higher if you have some USB>RS232 convertor that can support up to 921600). 2nd thing would be to use MODBUS driver mb_setAfterRegisterRead() callback procedure and do calculation there. After each even MODBUS register read command you immediately make new floating point calculation which will be ready for next MODBUS register read command. I don't think that theoretically you can be faster then that with MODBUS.

Please forgive me if I have (probably) misunderstood something.
Selected quotes for multi-quoting:   0

Registered users in this topic

Currently no registered users in this section

The statistic shows who was online during the last 5 minutes. Updated every 90 seconds.
MySQL Queries: 14 · Cache Hits: 14   77   91 · Page-Gen-Time: 0.019814s · Memory Usage: 2 MB · GZIP: on · Viewport: SMXL-HiDPI