bertmelis/VitoWiFi

Optolink remains busy after first write

s0170071 opened this issue · 10 comments

using v1.00 P300 I use this routine for reading / writing:

bool readWriteDP (word address, byte Len, uint8_t* rawdata, bool Write = false ){
  unsigned long now = millis(); 
  while (myOptolink.isBusy() && ((millis()-now) < 3000)) 
        delay(10);  // wait for optolink to become available
  if (myOptolink.isBusy() ) { 
      Serial1.print(F("optolink busy "));
      return false;
  }

  if (!Write) 
      myOptolink.readFromDP( address, Len);  // issue read command
  else 
      return myOptolink.writeToDP( address, Len, rawdata);

  while (((millis()-now) < 3000)){
        myOptolink.loop();
        if (myOptolink.available() > 0) {
          myOptolink.read(rawdata);
             return true; 
        }
        if (myOptolink.available() < 0) {
          Serial1.println(myOptolink.readError());
          return false; 
        }
  }
  return false;
}

This works for reading quite fine until the first write attempt. I then get the message "optolink busy" . The write succeeded but blocks the optolink from then on. Serial output is:

READ 410500012000042a
ack
RCV 41090101200004dc00b400bf
ack
Address 2000 has value DC00B400 (<--this is my read access)
Address 2000 data DC00 (<--this is my write access)
WRITE 41070002200002dc0007
ack
RCV 410501022000022a
ack

Could you do me a favour and try with the print commands in setState and setAction uncommented in the lib source code? I can give only limited support untill monday as I haven't got access to my computer.

Successful read


Optolink action: 1
Optolink state: 5
Optolink state: 6
READ 410500010101020a
ack
Optolink state: 7
RCV 41070101010102250133
Optolink state: 8
ack
Optolink state: 4
Optolink action: 2
Optolink action: 0
Address 101 has value 2501
29.30

successful write

Address 2000 data E600
Optolink action: 1
Optolink state: 5
Optolink state: 6
WRITE 41070002200002e60011
ack
Optolink state: 7
RCV 410501022000022a
Optolink state: 8
ack

failing reads since then

Optolink state: 4
Optolink action: 2
optolink busy timeout

Optolink state: 2
Optolink state: 3
Optolink state: 4
optolink busy timeout

optolink busy timeout

Optolink state: 2
Optolink state: 3
Optolink state: 4
optolink busy timeout

Optolink state: 2
Optolink state: 3
Optolink state: 4
optolink busy timeout


enum OptolinkState : uint8_t { RESET = 0, RESET_ACK, INIT, INIT_ACK, IDLE, SEND, SEND_ACK, RECEIVE, RECEIVE_ACK } _state;
enum OptolinkAction : uint8_t { WAIT = 0, PROCESS, RETURN, RETURN_ERROR } _action;

2 pint I should try:

  • change delay(10); to myOptolink.loop();
    just waiting could fill the UART buffer but VitoWiFi doesn't do anything with the data untill loop() is called.
  • don't return at return myOptolink.writeToDP( address, Len, rawdata);. Just do the same as when reading.

I removed the return and added loop() below the delay.
read gives now:

WiFi connected
IP address:
192.168.1.18
Setup finished...
Optolink state: 1
Attempting MQTT connection...connected
Optolink state: 0
Optolink state: 1
Optolink state: 0
Optolink state: 1
Optolink state: 2
Optolink state: 3
Optolink state: 4
Optolink action: 1
Optolink state: 5
Optolink state: 6
READ 410500010500040f
ack
Optolink state: 7
RCV 41090101050004092000003d
Optolink state: 8
ack
Optolink state: 4
Optolink action: 2
Optolink action: 0
Address 500 has value 09200000
8201.00

after some time:

Optolink state: 2
Optolink state: 3
Optolink state: 4
Optolink state: 2
Optolink state: 3
Optolink state: 4
Optolink state: 2
Optolink state: 3
Optolink state: 4

writing gives:

Address 2000 data E600
Optolink action: 1
Optolink state: 5
Optolink state: 6
WRITE 41070002200002e60011
ack
Optolink state: 7
RCV 410501022000022a
Optolink state: 8
ack
Optolink state: 4
Optolink action: 2
Optolink action: 0
Address 2000 has value E600

then reading :


Optolink state: 2
Optolink state: 3
Optolink state: 4
Optolink state: 2
Optolink state: 3
Optolink state: 4
Optolink action: 1
Optolink state: 5
Optolink state: 6
WRITE 41090002167004e60000007b
ack
Optolink state: 7
RCV 4106030216700120
Optolink state: 8
nack, length
Optolink state: 4
Optolink action: 3
Optolink action: 0
4
timeout

puh, it writes now the address it should have read.

but that is determined outside this code block?

VitoWiFi handles correct right? You cannot write to that address and timeouts.
Am I missing something?

Changing between states 2-4 is automatically for syncing.

side note: I must admit that the sequential design of your program is not what I had in mind when creating VitoWiFi.

There is something off here. The library writes when it should read. It says so at least. Not sure what it actually does. I inserted some printfs just to make sure what I call:
The *** watch... line I inserted manually ;-)


   if (!Write) {
        Serial1.println("calling readFromDP");
        myOptolink.readFromDP( address, Len);  // issue read command
        }
    else 
        {
          Serial1.println("calling writeToDP");
         myOptolink.writeToDP( address, Len, rawdata);
        }

The output of a boot, a read and a write is this:

WiFi connected
IP address:
192.168.1.18
Setup finished...
Optolink state: 1
Attempting MQTT connection...connected
Optolink state: 0
Optolink state: 1
Address: 1670 Len: 4 data: 00000000
calling readFromDP
Optolink action: 1
Optolink state: 0
Optolink state: 1
Optolink state: 2
Optolink state: 3
Optolink state: 4
Optolink state: 5
Optolink state: 6
READ 4105000116700490
ack
Optolink state: 7
RCV 41090101167004f21400009b
Optolink state: 8
ack
Optolink state: 4
Optolink action: 2
Optolink action: 0
Address 1670 has value F2140000
TempL:  536.20
TempS:  242.00
STAT:   true
CountL: 5362.00
CountS: 5362.00
Mode:   242.00
Hours:  1.49
CoP:    24.20
Raw:    f2140000


Address: 2000 Len: 2 data: E600
calling writeToDP
Optolink action: 1
Optolink state: 5
Optolink state: 6
WRITE 41070002200002e60011
ack
Optolink state: 7
RCV 410501022000022a
Optolink state: 8
ack
Optolink state: 4
Optolink action: 2
Optolink action: 0
Address 2000 has value E600
Address: 1670 Len: 4 data: E6000000

***** watch this: ********

calling readFromDP
Optolink action: 1
Optolink state: 5
Optolink state: 6
WRITE 41090002167004e60000007b
ack
Optolink state: 7
RCV 4106030216700120
Optolink state: 8
nack, length
Optolink state: 4
Optolink action: 3
Optolink action: 0
4
timeout

In OptolinkP300.cpp change lines 320-323

  if (write) {
    memcpy(_value, value, _length);
    _writeMessageType = true;
  }

to

  _writeMessageType = write;
  if (write) {
    memcpy(_value, value, _length);
  }

That did the trick.
Thanks.