B4R Question ESP8266 serial interrupts lost with wifi?

Bert Oudshoorn

Member
Licensed User
In a Serial (rs232) connection, commands of 3 bytes are sent to a PIC (microcontroller), byte by byte (just a one-byte buffer in the PIC), and echoed for timing. Tried a Delay(50) between the commands to give some time to the wifi stack, however, it fails after a few seconds. Without wifi activated (STA and AP mode) it works perfectly, so serial interrupts are lost?


B4X:
#Region Project Attributes
    #AutoFlushLogs: True
    #CheckArrayBounds: True
    #StackBufferSize: 300
#End Region
Sub Process_Globals
    Public Ser As Serial
    Private wifi As ESP8266WiFi   
    Private udp As WiFiUDP
    Private astream As AsyncStreams
    Private cnt As Byte
End Sub
Private Sub AppStart
    Dim d1(1) As Byte
    wifi.Connect2(<ssid>,<psw>)       'more rs232 losses in AP mode 
    udp.Initialize(6000,"UDPrec")        
    Ser.Initialize(115200) : Delay(2000)
    astream.Initialize(Ser.Stream, "RS232rec", Null)
    astream.WaitForMoreDataDelay = 0 : Delay(1000)
    d1(0) = 3 : astream.Write(d1)    
End Sub
Sub RS232rec(buf() As Byte) : Dim d1(1) As Byte
    cnt = (cnt + 1) Mod 3                  'send sequence of 3 bytes to PIC
    If cnt = 0 Then Delay(50)             'allow time for wifi stack, or yield()?
    d1(0) = 3 : astream.Write(d1)
    End Sub
Sub UDPrec(data() As Byte, IP() As Byte, Port As UInt)
    'not used for the test 
End Sub
 

Bert Oudshoorn

Member
Licensed User
Indeed, the PIC echoes the received byte, but once in a while RS232rec is not called. Strange, because the esp8266-01 is delivered with an AT firmware for a RS232-wifi "bridge". In the Kolban book (and github?), are 3 sleepmodes listed, one to disable "Modem" (wifi), but only for STA mode.
And somewhere a "yield()" statement was mentioned.
Secondly. what happens, if an UDPrec interrupt is received. while the (short) RS232rec routine is running.
Would that be stacked? So far, that works good, but I should test it better (longer RS232rec routine).
 
Upvote 0

Bert Oudshoorn

Member
Licensed User
Tried some native C without an interrupt (and no AsyncStreams). In B4R is an instance of Serial used, but in Arduino C is the baudrate specified on the "base" opbject? Erel, is the following code correct? (it works). I assume, that there are no serial read/write/available statements in B4R?

B4X:
#Region Project Attributes
    #AutoFlushLogs: True
    #CheckArrayBounds: True
    #StackBufferSize: 300
#End Region
Sub Process_Globals
    Private ssid As String = "MTesp2" 'ignore
    Private password As String = "MyTrains" 'ignore
     Private channel As Int = 1 'ignore
    Private udp As WiFiUDP
    Private x As Byte = 3 'ignore
    Private y As Byte     'ignore
    'Public Ser As Serial
    End Sub 
Private Sub AppStart
    RunNative("setSoftAP", Null)
    udp.Initialize(6000,"UDPrec")
    'Ser.Initialize(115200) : Delay(3000)
    RunNative("rs232begin", Null) : Delay(3000)
    Do While True
      RunNative("rs232", Null)
    Loop
    End Sub
Sub UDPrec(data() As Byte, IP() As Byte, Port As UInt)
    'not used in this test 
    End Sub
#if C
void setSoftAP(B4R::Object* o) {
    //WiFi.mode(WIFI_OFF);
    //WiFi.softAPdisconnect(true);
    WiFi.softAP(b4r_main::_ssid->data, b4r_main::_password->data, b4r_main::_channel);
}
void rs232begin(B4R::Object* q) {
    Serial.begin(115200);
}
void rs232(B4R::Object* r) {
    Serial.write(b4r_main::_x);  
    while (!Serial.available());   // echo by PIC 16F688
    b4r_main::_y = Serial.read();
}
#end if
 
Upvote 0

Bert Oudshoorn

Member
Licensed User
Indeed, I will try to generate pin interrupts from the PIC to indicate that a byte is "received/shipped", to check if those interrupts are 100% reliable.

Thank you for the Serial.Stream.--- Looks much better, and it runs as well.
 
Upvote 0

Bert Oudshoorn

Member
Licensed User
Indeed, I/O interrupts are also once in a while lost, as Serial interrupts, because of the WiFi implementation (?). Processing without interrupts works better. Tried it first via the Arduino IDE. B4R supports no polling udp (yet)? Such as: bufN = udp.parsePacket();
But tried a B4R version via a timer (50 msec). Waiting in the beginning (WiFi.status...) helps a lot, to allow WiFi to settle. The 200 usec delay is needed for some of my 8 esp8266-01 items. Somebody mentioned less quality flash memory(?). The test: exchanging 3 bytes with a PIC via Serial. The first byte is default 3, but can be changed via UDP.
Note: The led flashes stable in the Arduino C, but "waves" (dimming) a little with B4R (period about 1 second).
Detail: The PIC is programmed with JAL (Just Another Language). No bootloader, so a programmer is needed. Not listed here.

B4X:
#Region Project Attributes
    #AutoFlushLogs: True
    #CheckArrayBounds: True
    #StackBufferSize: 300
#End Region
Sub Process_Globals
    Private ssid As String = "***"            'ignore
    Private password As String = "********"    'ignore
     Private channel As Int = 1                'ignore
    Private udp As WiFiUDP            : Public Ser As Serial
    Private timCmd As Timer         : Private led As Pin
    Private x As Byte = 0             : Private i As Byte
    End Sub                
Private Sub AppStart
    led.Initialize(2, led.MODE_OUTPUT) : led.DigitalWrite(True)
    RunNative("setSoftAP", Null)
    udp.Initialize(6000,"UDPrec") : Delay(2000) '// delay needed ?
    Ser.Initialize(115200) : Delay(1000)    '// PIC start-delay 3000
    timCmd.Initialize("CMDtim",50) : timCmd.enabled = True
    End Sub
Sub CMDtim : Dim buf(1) As Byte : buf(0) = 3
    If x <> 0 Then : buf(0) = x : x = 0 : End If
    For i = 0 To 2
      Ser.Stream.WriteBytes(buf,0,1)
      led.DigitalWrite(False)                  '// ON, led to 3.3 V
      Do While (Ser.Stream.ReadBytes(buf,0,1) < 1)
        DelayMicroseconds(200) : Loop        '// FOR BAD FLASH MEMORY ?
      led.DigitalWrite(True)
      buf(0) = 47                            '// byte 0=3, 1=47, 2=47   
    Next
    End Sub
Sub UDPrec(buf() As Byte, IP() As Byte, Port As UInt)
    x = buf(0)                                '// from B4A Android phone
    End Sub       
#if C
void setSoftAP(B4R::Object* o) {  uint8_t i = 0;
   WiFi.softAP(b4r_main::_ssid->data, b4r_main::_password->data, b4r_main::_channel);
   while (WiFi.status() != WL_CONNECTED && i++ < 20) delay(500); }
#end if
 
Upvote 0
Top