B4R Question software serial not reading data

atiaust

Active Member
Licensed User
Longtime User
Hi,

I have a software serial connection that reads data from a serial device. The serial data is sent from the transmitting device every 60 seconds. The software serial is on pins D6 (RX) & D7 (TX) on a Wemos D1 Mini.

The serial data is read in the first instance and displayed in the logs.

The data is never read again until I restart the device however I can monitor the data on the RX pin with an oscilloscope and the data is received every 60 seconds as it should be.

It appears the input (RX pin) ignores the data.

Is it better to use the RX & TX pins instead of the software serial setup D6 & D7?

Does anyone have any ideas?

Thanks
 

emexes

Expert
Licensed User
Without seeing the code, this is just a random stab in the dark, but: perhaps your receiver is in prefix mode, and the transmitter is not.

But if the first packet is received corectly... hmm...

Another problem with software serial is that it usually does not cope will with high baud rates, but again... there's that pesky first packet.

Just to clarify: each time you restart your app, it receives one packet (are the bytes exactly correct?) and then ignores further data from the same pin?
 
Upvote 0

atiaust

Active Member
Licensed User
Longtime User
Hi emexes.

The baud is 9600. The first packet is exactly correct and not using prefix mode.

I am using a Max3232 RS323 to TTL converter.

I am fresh out of ideas.

Thanks
 
Upvote 0

emexes

Expert
Licensed User
Can you make the transmitting device transmit once per second or two, instead of once every 60 seconds?

Or what happens if you make the first transmission longer, or transmit the packet twice back-to-back?

Or it could be that your program is doing something that uses up memory, in the 59 seconds between the first and second serial transmissions. Per:

https://www.b4x.com/android/forum/threads/memory-variables-and-objects.65672/

check StackBufferUsage, and perhaps try setting a larger stacksize with #StacBufferSize.

I was going to ask you to check:
The library has the following known limitations:
- If using multiple software serial ports, only one can receive data at a time.
- Not all pins on the Mega and Mega 2560 support change interrupts, so only the following can be used for RX: 10, 11, 12, 13, 14, 15, 50, 51, 52, 53, A8 (62), A9 (63), A10 (64), A11 (65), A12 (66), A13 (67), A14 (68), A15 (69).
- Not all pins on the Leonardo and Micro support change interrupts, so only the following can be used for RX: 8, 9, 10, 11, 14 (MISO), 15 (SCK), 16 (MOSI).
- On Arduino or Genuino 101 the current maximum RX speed is 57600bps
- On Arduino or Genuino 101 RX doesn't work on Pin 13
from https://www.arduino.cc/en/Reference/softwareSerial but the Wimos D1 Mini documentation I've seen says that all D* pins have interrupt capability, so...
 
Upvote 0

atiaust

Active Member
Licensed User
Longtime User
Hi,

The code is pretty simple.

I take the RS232 reading and then send it out on an MQTT connection.

To answer emexes, the controller is propriety so I am unable to change any of its functionality.

B4X:
#Region Project Notes
'
#End Region

#Region Project Attributes
    #AutoFlushLogs: True
    #CheckArrayBounds: True
    #StackBufferSize: 400
#End Region
'
Sub Process_Globals
'    Serial   
      Public Serial1 As Serial                'Serial connection for Debug..
    Public Serial2 As SoftwareSerial        'RS232 connection to SM70 Ozone board
'   
    Private bc As ByteConverter
    Private wifi As ESP8266WiFi
    Private WiFiStr As WiFiSocket
      Private server As WiFiServerSocket
      Private astream1 As AsyncStreams
    Private astream2 As AsyncStreams
    Public connected(2) As Boolean
     Private ser As B4RSerializator
'   
    Public id As String    = "1000" ' ID string for this controller to use with MQTT ******* Change this for each controller
'                                    may use MAC address ??
'    My test network
    Private ssid As String = "OBS_Ozone"
    Private pwd As String = "oxyzone1"
'   
    Private D1 As D1Pins
    Private led As Pin
    Private t1 As Timer
'
'MQTT
      Private mqtt As MqttClient
    Private MqttTopicOzone As String = "ozone"   
    Private MqttTopicAlarm As String = "alarm"
    Private mqttTopicRaw As String = "raw"
    Public ppm As Double    'transmitted ppm of ozone.
'
'Sensor
    Private alarm As Pin    'alarm pin from Aeroqual SM70
'Server   
    Private serverIP() As Byte = Array As Byte(192, 168, 10, 128 )
    Private const ServerPort As UInt = 1883    'MQTT Port
'
End Sub

'
Private Sub AppStart
      Serial1.Initialize(115200)
     Log("AppStart")
'   
    t1.Initialize("t1_Tick",1000)
    led.Initialize(D1.D4,led.MODE_OUTPUT)   
    t1.Enabled = True
    '
    If wifi.Connect2(ssid,pwd) Then 'change to your network SSID (use Connect2 if a password is required).
        Log("Connected to wireless network.")
        Log("My ip: ", wifi.LocalIp)
        t1.Enabled = False
        led.DigitalWrite(False)
    Else
        Log("Failed to connect.")
        t1.Enabled = True    ' blink Blue LED if we have a valid connection
        Return
    End If
'   
    server.Initialize(51042, "server_NewConnection")
    server.Listen
'   
    Serial2.Initialize(9600,12,13)    ' Wemos D6(GPIO12) for RX , D7(GPIO13) for TX
    astream2.Initialize(Serial2.Stream, "astream2_NewData", "astream2_Error")
'
    mqtt.Initialize(WiFiStr.Stream, serverIP, ServerPort, id, "Mqtt_MessageArrived", "Mqtt_Disconnected")
'   
    alarm.Initialize(D1.D3,alarm.MODE_INPUT_PULLUP)
'
    MQTTConnect(0)
' 
    alarm.AddListener("alarm_StateChanged")   
 '
End Sub

'Alarm input - alarm is held high by WEMOS internal Pull-Up resistor. Alarm contacts connected to ground when alarm energises
'send alarm signal via MQTT
Sub alarm_StateChanged (state As Boolean)
    If state = False Then    'alarm contacts pull input low (alarm on)
        Dim o As String = "True"
        Dim s As String = JoinStrings(Array As String(id,",", o))
        mqtt.Publish(MqttTopicAlarm,s.GetBytes)
    Else
        Dim o As String = "False"        'alarm contacts open and input goes high via pull-up
        Dim s As String = JoinStrings(Array As String(id,",", o))
        mqtt.Publish(MqttTopicAlarm,s.GetBytes)
    End If
'   
End Sub

'
Sub Server_NewConnection (NewSocket As WiFiSocket)
    Log("Client connected")
    astream1.Initialize(NewSocket.Stream, "astream1_NewData", "astream1_Error")
End Sub

'
Sub AStream1_NewData (Buffer() As Byte)
    Dim be(10) As Object
    Dim data() As Object = ser.ConvertBytesToArray(Buffer, be)
    Log("Received:")
    For Each o As Object In data
        Log(o)
    Next
End Sub

'
Sub AStream1_Error
    Log("Error")
    server.Listen
End Sub

'MQTT
#Region MQTT
Sub MQTTConnect(unused As Byte)
    If mqtt.Connect = False Then
        Log("MQTT: trying to connect again")
         CallSubPlus("MQTTConnect", 1000, 0)
         Return
       End If
       Log("MQTT: Connected to the broker")
'    Subscribe to the 'ozone' topic which is published by the server to confirm temperature received
       mqtt.Subscribe(MqttTopicOzone, 0)
'   
End Sub

'Handle Message arrived
Sub Mqtt_MessageArrived (Topic As String, Payload() As Byte)
    Log("MQTT: Message arrived. Topic=", Topic, " Payload: ", Payload)
End Sub

'Publish MQTT Message
Sub Mqtt_Publish(aa As String)
    Dim s As String = NumberFormat(ppm,0,2)
    Dim k As String = JoinStrings(Array As String(id,",",s,",",aa))
    mqtt.Publish(MqttTopicOzone,k.GetBytes)
End Sub

'Mqtt Disconnect
Sub Mqtt_Disconnected
    Log("MQTT: Disconnected")
    mqtt.Close
    MQTTConnect(0)            'should reconnect after disconnection        03/02/2019
End Sub
#End Region

'RS232 Serial connection
Sub astream2_newData (Buffer() As Byte)    '
'    *******   
'    This bit is for testing
    Dim a As String = bc.HexFromBytes(Buffer)        'contents of buffer in Hex        =    AA101DFCA43C0000000048006000A5
    mqtt.Publish(mqttTopicRaw,a)
    Log("a = ",a)
    Log("buffer len = ",Buffer.Length)                'len of buffer
    Log (bc.SubString2(a,4,12))                        'get bytes 3 to 6 from string    =     1DFCA43C
'    ********
'    If connected(0) Then            ' if there is a WIFI connection then write the buffer out to connected B4J or B4A apps
'        astream(0).write(Buffer)
'    End If
'
'    Position
'        0            AA = Sensor type    (1 byte)
'        1            10 =                 (1 byte)
'        2            1DFCA43C = Reading    (4 bytes) - little Endian - Hex bit backwards
'        6            Reserved            (6 Bytes)
'        12            Status                (1 Byte)    -b1b0 = 00 Sensor OK, 01 = sensor failing, 11 = sensor ageing - Bit 7 - 2 not used..
'        13            Reserved
'        14            Check sum
'   
'    Get the status of the sensor
    Dim s(1) As Byte
    bc.ArrayCopy2(Buffer,12,s,0,1)
'    Log("s = ",s(0))
    Dim res(8) As Byte
    ByteToBinary(s(0), res)
'    Log("sensor = ",res)
    Dim sen As String = bc.StringFromBytes(res)
'    Log("sen = ",sen)
    Dim z() As Byte = bc.SubString(sen,6)
    Log("sensor status = ",z)                'z = the sensor status "00" = OK, "01" = sensor failing, "11" = sensor aging
    Dim t As String = bc.StringFromBytes(z)
'
'    Dim Buffer() As Byte = bc.HexToBytes("AA101DFCA43C0000000048006000A5") 'you don't need this line
    Dim b(4) As Byte
    bc.ArrayCopy2(Buffer, 2, b, 0, 4)
    Dim d() As Double = bc.DoublesFromBytes(b)
'    Dim ppmOZ As String = NumberFormat(d(0),1,2)
    Log("ppm = ",d(0))                        'd(0) is the current ppm reading from the sensor
    ppm = d(0)
'
    Mqtt_Publish(t)
'
    
End Sub

'
Sub astream2_Error
    Log("Serial 2 - No Connection")
    mqtt.Publish(mqttTopicRaw,"Astream2 error")
End Sub

'
Sub ByteToBinary (Number As Byte, Result() As Byte)
    For i = 0 To 7
        If Bit.Get(Number, 7 - i) = 1 Then
            Result(i) = Asc("1")
        Else
            Result(i) = Asc("0")
        End If
    Next
End Sub

Sub t1_tick
    'turn led on and off every second to show its waiting for a connection
    Dim currentState As Boolean = led.DigitalRead
    '   Log("CurrentState: ", currentState)
    Dim NewState As Boolean = Not(currentState)
    '   Log("NewState: ", NewState)
    led.DigitalWrite(NewState)
End Sub
 
Upvote 0
Top