B4R Question Serial text without carriage return is not recognized.

Tim Chapman

Active Member
Licensed User
Longtime User
I added an EMIC 2 speech synthesizer to my robot project.
It works beautifully.
When it finishes speaking, it sends a colon ":" our of its serial port.
That serial data is received on the Hardware Serial Port 2 of my Arduino Mega 2560.
Since it has no carriage return, the data is not seen by the Arduino.
Is there any way to fix this?

Line 55 of my code below is not sending anything. But it works correctly in other instances.

This is the relevant code:

My B4R Code:
Sub Process_Globals
    'TXD2/RXD2 Serial for EMIC 2 Text to Speech Synthesizer.  See:  D:\Electronics\Data Sheets\Emic 2 Text to Speech Module
    Private SerialNative2 As Stream 'https://www.b4x.com/android/forum/threads/additional-hardware-serial-ports.67150/
    Private Emic2Stream As AsyncStreams
End Sub

Private Sub AppStart
    'Serial for EMIC 2 Text to Speech Synthesizer connected to Hardware Serial Port 1.
    RunNative("SerialNative2", Null)
    Emic2Stream.Initialize(SerialNative2, "Emic2Stream_NewData", Null)
   
        Delay(2000)
   
    CommandEMIC2("H","")
    Delay(5000)
   
    For VoiceNumber = 0 To 8

    CommandEMIC2("N",VoiceNumber)
        Delay(1000)

        CommandEMIC2("V", 18)
       
        Delay(1000)
        Speak("Hello! My name is Emic 2. Nice to meet you.")
        Delay(5000)
    Next
End Sub

Private Sub Speak(SendData As String)
    Private eol2() As Byte = Array As Byte(13)
        Dim SendData As String = JoinStrings(Array As String("S", SendData))
        'Log("Send Data = ", SendData)

        'Send data to EMIC 2 connected to Hardware Serial Port 2.
        Dim Buffer() As Byte = SendData
        Emic2Stream.Write(Buffer)
        Emic2Stream.Write(eol2) 'end of line character. AsyncStreamsText will cut the message here
End Sub

Private Sub CommandEMIC2(SendData1 As String, SendData2 As String)
    Private eol2() As Byte = Array As Byte(13)
        Dim SendData As String = JoinStrings(Array As String(SendData1, SendData2))
        Log("Command Data = ", SendData)

        'Send data to EMIC 2 connected to Hardware Serial Port 2.
        Dim Buffer() As Byte = SendData
        Emic2Stream.Write(Buffer)
        Emic2Stream.Write(eol2) 'end of line character. AsyncStreamsText will cut the message here
End Sub

Private Sub Emic2Stream_NewData (Buffer() As Byte) 'Data from EMIC 2 Text to Speech Synthesizer
    Log("Buffer = ", Buffer)
    Private eol2() As Byte = Array As Byte(13)
    PCStream.Write(Buffer) 'Send data out via Bluetooth connection to bluetooth receiver on the PC.
    PCStream.Write(eol2) 'end of line character. AsyncStreamsText will cut the message here
End Sub
 

Tim Chapman

Active Member
Licensed User
Longtime User
Hi Emexes. I received email about your post and read it but your post is not showing here. There is an oops! error when I click on the link in my email saying the post can't be found. Maybe I will have a chance to check how this works later. I like the most elegant and simple solution in coding when I can find it. However, right now, I have priorities I have to attend to. Thank you very much for your assistance on all of this.
 
Upvote 0

janderkan

Well-Known Member
Licensed User
Longtime User
In your code there is no definition of PCStream.

I use hardware serial ports on ESP32 a lot but when I write code I never use delays.
Try using flags and a state machine, then your code is never blocked.
 
Upvote 0

emexes

Expert
Licensed User
software to do it right no matter what
Maybe I will have a chance to check how this works later.

Lol I'm a quiet person who doesn't enjoy being the bearer of bad news so I figured I'd get Grok to do it for me.

Good news is that Grok was firmly on your side, until I pointed out that a value over 4 billion is larger than a value under 4 billion.

Took some arm-twisting but we got there in the end:

https://x.com/i/grok/share/KOTatmhSRCUgMP0OV6tycQVQX
 
Last edited:
Upvote 0

emexes

Expert
Licensed User
There is another issue which is that, If Millis > 4294965295 Then RobotStopTimerStart is being set to the end of the delay, rather than the beginning, thus doubling the duration of the delay.

Looking on the bright side: is better to have too long a delay than none at all.

There are ways to bludgeon your code into working, but none of it is pretty.

Go with:

B4X:
RobotStopTimerStart = Millis

Do Until Millis - RobotStopTimerStart > 2000    'Allow 2 seconds for the robot to stop
Loop

It's like I've been down this rabbit hole before. First time was 1987 with Turbo Basic, then a couple of years later with 8-bit timers in car ECU microcontrollers. I've had some time to get it right. Modulo arithmetic is not the walk in the path that it first looks like. 🍻
 
Last edited:
Upvote 0

emexes

Expert
Licensed User
Go with:

B4X:
RobotStopTimerStart = Millis

Do Until Millis - RobotStopTimerStart > 2000    'Allow 2 seconds for the robot to stop
Loop

This worked example (for a delay of 17-and-a-bit ms rather than 2000-and-a-bit ms) might make it make sense:
(and again, I agree that modulo arithmetic is enough to drive one to 🍺 )

1736256729337.png
 
Last edited:
Upvote 0
Top