B4R Question fail to send DATA to seriaL

hi
i want to send 346 file ( each file is 2016 byte ) to serial ( for update a device firmware )
i send first file and revice device request from serial for next file , then i send second file and ...
when i set baudrate to 38400 , my program work perfect , but its too slow ( about 4 min ) ..
when i change baudrate to 115200 , and set device baudrate to 115200 , all files not send to device perfect and after sending 200 files , the files send curropted .. and because device not recive correct data , not send request to next file... and its stop..
my arduino is 2560
my code is :
B4X:
#Region Project Attributes
#AutoFlushLogs: true
#StackBufferSize: 2000
#CheckArrayBounds: true
#End Region

Sub Process_Globals
   Public Serial1 As Serial
   Private sd As SD
   Private softserial As SoftwareSerial
   Private astream As AsyncStreams
   Private bc As ByteConverter
End Sub

Private Sub AppStart
    Serial1.Initialize(115200)
    Log("AppStart")
    softserial.Initialize(38400,11, 16)
    astream.Initialize(softserial.Stream  , "astream_newdata", "AStream_Error")
    sd.Initialize(53)
End Sub

Sub astream_newdata (buffer1() As Byte)
    Log("Recived Data : ",bc.HexFromBytes(buffer1))
    Dim hh As String = bc.HexFromBytes(buffer1)
   If hh.Length > 3 Then
    send_to_serial (hh)
   End If
End Sub

Sub send_to_serial (hh As String)
    Dim file As String = get_file_name(hh)
    If sd.OpenRead (file) = True Then
                    Dim cb (2061) As Byte
                    sd.Position =0
                    sd.Stream.ReadBytes(cb, 0, 2061)
                    astream.Write(cb)
        End If
   sd.close
End Sub

Sub get_file_name(block As String ) As String
    If bc.SubString2(block,0,5)="0F370" And block.Length =16 Then
        Dim adadesh As String = bc.StringFromBytes(bc.SubString2(block,5,8))  ' 050
        Dim i As Int = Bit.ParseInt(bc.StringFromBytes(adadesh), 16) + 3
        Dim str_adad As String = i
        Dim file_name As String  = JoinStrings(Array As String(str_adad, ".dat"))
        Return file_name
    End If
Return  "error"
End Sub


Sub AStream_Error
    Log("Error In serial Port")
End Sub
 
The first step is to switch from SoftwareSerial to a hardware serial: https://www.b4x.com/android/forum/threads/67150/#content
hi erel
i use both hardware serial2 and serial3 , but my problem not solve.

my code that use hardware serial is:


B4X:
#Region Project Attributes
#AutoFlushLogs: true
#StackBufferSize: 2000
#CheckArrayBounds: true
#End Region

Sub Process_Globals
    Public Serial1 As Serial
    Private SerialNative2 As Stream
    Private sd As SD
    Private astream As AsyncStreams
    Private bc As ByteConverter
End Sub

Private Sub AppStart
   
    Log("AppStart")
    RunNative("SerialNative2", Null)
    astream.Initialize(SerialNative2, "astream_NewData", Null)
    sd.Initialize(4)
End Sub



Sub astream_newdata (buffer1() As Byte)
    Log("Recived Data : ",bc.HexFromBytes(buffer1))
    Dim hh As String = bc.HexFromBytes(buffer1)
    send_to_serial (hh)
End Sub


Sub send_to_serial (hh As String)
    Dim file As String = get_file_name(hh)
    If sd.OpenRead (file) = True Then
       
            Dim cb (2061) As Byte
            sd.Position =0
            sd.Stream.ReadBytes(cb, 0, 2061)
            astream.Write(cb)
        End If
        sd.close
End Sub


Sub get_file_name(block As String ) As String
    If bc.SubString2(block,0,5)="0F370" And block.Length =16 Then
        Dim adadesh As String = bc.StringFromBytes(bc.SubString2(block,5,8))  ' 050
        Dim i As Int = Bit.ParseInt(bc.StringFromBytes(adadesh), 16) + 3
        Dim str_adad As String = i
        Dim file_name As String  = JoinStrings(Array As String(str_adad, ".dat"))
        Return file_name
    End If
    Return  "error"
End Sub


Sub AStream_Error
    Log("Error In serial Port")
End Sub

#if C
void SerialNative2(B4R::Object* unused) {
   ::Serial2.begin(38400);
  b4r_main::_serialnative2->wrappedStream = &::Serial2;
}
#end if
 
Upvote 0
Where is the code of the receiving side? Maybe a part of the next file is being saved in the current file.
Try to call SerialNative2.Flush after you write the file and add a short delay.
Reciving side is a hardware. i send data to a hardware device and i have not access to software of that device.
but when i send this 346 files with software ( vb.net software ) and set baudrate to 115200 or 460800 , it recive correct and software works good .
 
Upvote 0
You might need to lower the baud rate. Test it with other values.

You can also write a small B4J program that receives the data from the serial port. It might shed some light on the corrupted data.
i test it with baudrate 38400 and it work perfect. but its slow..
i monitor serial port ( send and recive data between arduino and device ) .. after sending 200 file , file 201.dat not send correct from arduino to device..
i think serial buffer overflow..
can i change serial buffer or other parameter of serial ?
 
Upvote 0

Mostez

Well-Known Member
Licensed User
Longtime User
I had a similar problem like that, I had to send text file to bar code printer, it was about stack buffer size and usage of memory. Try to test stack size usage. you're using joinstring and it consumes memory, also try to reduce sub calls, if you have to then use global store to pass returned values instead, it works like a charm.
 
Upvote 0
It might be possible to change the serial buffer by editing the Arduino libraries. However you can instead split the data and send it with short delays.
i split data before send to serial port , but problem not solved...

B4X:
#Region Project Attributes
#AutoFlushLogs: true
#StackBufferSize: 2000
#CheckArrayBounds: true
#End Region

Sub Process_Globals
    Public Serial1 As Serial
    Private SerialNative2 As Stream
    Private sd As SD
    Private astream As AsyncStreams
    Private bc As ByteConverter
End Sub

Private Sub AppStart
   
    Log("AppStart")
    RunNative("SerialNative2", Null)
    astream.Initialize(SerialNative2, "astream_NewData", Null)
    sd.Initialize(4)
End Sub



Sub astream_newdata (buffer1() As Byte)
    Log("Recived Data : ",bc.HexFromBytes(buffer1))
    Dim hh As String = bc.HexFromBytes(buffer1)
    send_to_serial (hh)
End Sub


Sub send_to_serial (hh As String)
    Dim file As String = get_file_name(hh)
    If sd.OpenRead (file) = True Then
       
    For y = 0 To 2061 Step 512
            If y <> 2048 Then
                Dim cb (512) As Byte
                sd.Position =y
                sd.Stream.ReadBytes(cb, 0, 512)
                astream.Write(cb)
            Else
                Dim cb (13) As Byte
                sd.Position =y
                sd.Stream.ReadBytes(cb, 0, 13)
                astream.Write(cb)
            End If
        Delay(100)
    Next
   
   
   
    End If
        sd.close
End Sub


Sub get_file_name(block As String ) As String
    If bc.SubString2(block,0,5)="0F370" And block.Length =16 Then
        Dim adadesh As String = bc.StringFromBytes(bc.SubString2(block,5,8))  ' 050
        Dim i As Int = Bit.ParseInt(bc.StringFromBytes(adadesh), 16) + 3
        Dim str_adad As String = i
        Dim file_name As String  = JoinStrings(Array As String(str_adad, ".dat"))
        Return file_name
    End If
    Return  "error"
End Sub


Sub AStream_Error
    Log("Error In serial Port")
End Sub

#if C
void SerialNative2(B4R::Object* unused) {
   ::Serial2.begin(38400);
  b4r_main::_serialnative2->wrappedStream = &::Serial2;
}
#end if
 
Upvote 0
my problem solved by sending one by one bytes to serial and add delay(0)

B4X:
    For y = 0 To (2060)
                    Dim cb (1) As Byte
                    sd.Position =y
                    sd.Stream.ReadBytes(cb, 0, 1)
                    astream.Write(cb)
                    Delay(0)
            Next

thanks every body...
 
Upvote 0
Top