B4R Question String.split into an array..how?

jimseng

Member
Licensed User
Longtime User
I am receiving a comma separated string eg "100,150,175,200" from a PC via USB:
I am trying to get it into an array such as:
dim i(3) as int
dim count as int
Dim c As String = (JoinStrings(Array As String(BC.StringFromBytes(Buffer))))
from the tutorial I can split it around the comma:
For Each s() As Byte In bcx.Split(c,",")
count = count + 1
i(count) = s
R.AnalogWrite(i(count))
G.AnalogWrite(i(count))
B.AnalogWrite(i(count))
W.AnalogWrite(i(count))


next

This doesn't work (Cannot cast type). There must be a more elegant way of doing this.
Hopefully it is obvious what I am trying to do-write the values of the string to 4 pwm outputs.

How might I acheive this.

Many thanks
 

Mark Read

Well-Known Member
Licensed User
Longtime User
Firstly, before DonManfred or Erel gets to you, please use the code tags (left from the disk) when posting. It makes your code easier to read.

What exactly are you getting from the USB port, a string or bytes?
 
Upvote 0

Mark Read

Well-Known Member
Licensed User
Longtime User
I think you were lloking here maybe? Link At this code:

B4X:
Dim b() As Byte = " abc,def,ghijkl "
   Log("Substring: ", bc.SubString(b, 3)) 'Substring: c,def,ghijkl
   For Each s() As Byte In bc.Split(b, ",")
     Log("Split: ", s)
     'Split: abc
     'Split: def
     'Split: ghijkl
   Next

In this case "s" is an array and you can call each member s(0), s(1) etc.
 
Upvote 0

jimseng

Member
Licensed User
Longtime User
Wow I have been at this four hours and really don't understand.

So I am sending from a terminal something like 100,200,220,254 (Arduino serial port monitor)

All I want to do is split the string around the comma and get an integer value from it that I can write to an analogue pin
(eg
B4X:
R.AnalogWrite(254)
)
log(s) returns the values "correctly"
B4X:
log(s1)
returns something like 49. If done in a loop it returns 48 48 51 53

if I send a string such as 1,2,3,4 I get "Out of bounds error. Array length = 1, Index = 1"

I would have thought this would be so simple but I haven't found an example that helps me, and I have been searching for hours. I am new to this. (Can you tell?)
 
Upvote 0

Mark Read

Well-Known Member
Licensed User
Longtime User
Not a problem being new, we were all new sometime. Can you post your whole code or zip it and post?

Where are you sending from and where is is going?
 
Upvote 0

jimseng

Member
Licensed User
Longtime User
Currently I am using the Arduino IDE serial port monitor to send a simple string. Next I will be using a VB.net app but I don't know where this is going. It is just a bit of fun but it might involve raspberry pi/bluetooth. I guess I should be sending bytes instead of strings but I am trying to keep it generic for now.
I am investigating RGBW LEDS for a home lighting project using the PWM outputs from the Arduino.

No animals will be harmed in the process of developing this project.
 

Attachments

  • rgbw.zip
    1 KB · Views: 194
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
Next I will be using a VB.net app but I don't know where this is going
Don't. Start with this: https://www.b4x.com/android/forum/threads/tool-external-serial-connector.65724/#content

You cannot directly convert arrays of bytes to numbers. You must first convert it to string:
B4X:
Dim bc As ByteConverter
[code]
For Each s() As Byte In bcx.Split(c,",")
count = count + 1
i(count) = bc.StringFromBytes(s)

Make sure to set #StackBufferSize to 600 or more.

Strings are the least suitable format for communication with microcontrollers. Your best option is to use B4RSerializator.
 
Upvote 0

jimseng

Member
Licensed User
Longtime User
I have been looking at the B4RSerializator but not got anywhere. I get "Out of bounds error. Array length = 150, Index = 65535 " when sending 4 bytes from my .net app.
I have tried the b4j example, which doesn't really seem any different from hyperterminal or some other serial comms. I must be approaching this badly but I see no examples that come close to what I'm after.
 
Upvote 0

jimseng

Member
Licensed User
Longtime User
I had a quick dabble within the arduino IDE and perhaps the attached sketch would demonstrate what I am trying to do. I would rather stick with B4R as it is more familiar to me. This Arduino sketch works well when sending bytes from vb.net (rather than strings). If I could achieve this in B4R I would be much happier.
 

Attachments

  • serial.txt
    657 bytes · Views: 195
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
Upvote 0

Johan Hormaza

Well-Known Member
Licensed User
Try this code, it worked perfectly for me.
B4X:
Sub ReceiveFileName (Buffer() As Byte)
    Dim J As Byte = 0
    Dim Anio, mes, hora, Dia, minutos As Object
    Log("Bufer File: ",Buffer)
    Log("Trim: ", bc.Trim(Buffer)) 
    For Each s() As Byte In bc.Split(Buffer, "/")
        j = j + 1

        Select J
            Case 1
                Anio = bc.stringfrombytes(s)
            Case 2
                mes = bc.stringfrombytes(s)
            Case 3
                Dia = bc.stringfrombytes(s)
            Case 4
                hora = bc.stringfrombytes(s)
            Case 5
                minutos = bc.stringfrombytes(s)
        End Select
        Log("Split: ", s, "Posicion: ", J)
    Next
    Log("AƱo: ",Ano," Mes: ",mes," Dia: ",Dia," Hora: ",hora," Min: ",minutos)
    DateTimes(Anio,mes,Dia,hora,minutos)
    void_loop.Enabled = True
End Sub

Sub DateTimes(Anio As Object, mes As Object, Dia As Object, Horas As Object, Minutos As Object)
.
.
.
 
Upvote 0

hvvdl

Member
Help Me!!!!!!!!!!!!
I code
B4R:
Private Sub AppStart
    Serial1.Initialize(9600)
    Log("AppStart")
    If wifi.Connect("TOTOLINK_N600R") Then
        'If wifi.Connect2("3G uFi_B1D","1234567890") Then
        'If wifi.Connect2("4213b","12345668") Then
        Log("Waiting for connection.")
        Log("My ip: ", wifi.LocalIp)
        Dim bc As ByteConverter'= wifi.LocalIp
        Dim AA As String=bc.StringFromBytes(wifi.LocalIp)
            For Each s() As Byte  In bc.Split(AA,".")
            Log(s)
        Next
        Dim port As Int =10000 + Bit.ParseInt(s(3),16) '+ bc.IntsFromBytes( s(3))
        Log(port)
        server.Initialize(port, "server_NewConnection")
        server.Listen
        timer1.Initialize("timer1_Tick", 500)
        pin.Initialize(3, pin.MODE_OUTPUT)
    Else
        Return
    End If
End Sub

but error same image belows : Out of bound error. Array length =1, Index =3
 

Attachments

  • errorB4r.jpg
    errorB4r.jpg
    10.1 KB · Views: 74
Upvote 0

emexes

Expert
Licensed User
I don't have B4R but I suspect this is what is happening:

When the For Each loop finishes, S() = "2" ie the last field of the IP address AA when split by "."

The S() array/string is a single (ie one) element/character long, being S(0) = '2'

In the Dim Port line, you are then trying to access the 4th element/character S(3) which does not exist in the single-element/character array/string.
 
Upvote 0

Mark Read

Well-Known Member
Licensed User
Longtime User
Help Me!!!!!!!!!!!!
I code
B4R:
Private Sub AppStart
    Serial1.Initialize(9600)
    Log("AppStart")
    If wifi.Connect("TOTOLINK_N600R") Then
        'If wifi.Connect2("3G uFi_B1D","1234567890") Then
        'If wifi.Connect2("4213b","12345668") Then
        Log("Waiting for connection.")
        Log("My ip: ", wifi.LocalIp)
        Dim bc As ByteConverter'= wifi.LocalIp
        Dim AA As String=bc.StringFromBytes(wifi.LocalIp)
            For Each s() As Byte  In bc.Split(AA,".")
            Log(s)
        Next
        Dim port As Int =10000 + Bit.ParseInt(s(3),16) '+ bc.IntsFromBytes( s(3))
        Log(port)
        server.Initialize(port, "server_NewConnection")
        server.Listen
        timer1.Initialize("timer1_Tick", 500)
        pin.Initialize(3, pin.MODE_OUTPUT)
    Else
        Return
    End If
End Sub

but error same image belows : Out of bound error. Array length =1, Index =3

This is a very old thread. It would be better to start a new thread and give more details on what you are trying to do. Normally the bytes received should be read in a separate sub. Here you should check the number of bytes you have received against the number you expect.

Even if you send the numbers (eg. 123.456.789.321) as bytes, they might not all appear at once.

Where is the data coming from? Where is it going to? What is the connection type, UDP, MQTT etc?

A quick check would be logging "AA" in your code. Does it show what you have sent?
 
Upvote 0

hvvdl

Member
I
B4R:
    Dim bc As ByteConverter'= wifi.LocalIp
        Dim AA As String=bc.StringFromBytes(wifi.LocalIp)
        Dim Pc As Int
        For Each s() As Byte  In bc.Split(AA,".")
            Log(s)
            Pc=bc.StringFromBytes(s)
        Next
        Dim port As Int =10000 + Pc 'Bit.ParseInt(s(2),16) '+ bc.IntsFromBytes( s(3))
solved
 
Upvote 0

hvvdl

Member
This is a very old thread. It would be better to start a new thread and give more details on what you are trying to do. Normally the bytes received should be read in a separate sub. Here you should check the number of bytes you have received against the number you expect.

Even if you send the numbers (eg. 123.456.789.321) as bytes, they might not all appear at once.

Where is the data coming from? Where is it going to? What is the connection type, UDP, MQTT etc?

A quick check would be logging "AA" in your code. Does it show what you have sent?
I'm new to B4r so old to you but new to me.
 
Upvote 0

Mark Read

Well-Known Member
Licensed User
Longtime User
I'm new to B4r so old to you but new to me.

Welcome to the forum. I am glad that you managed to solve your problem. šŸ‘

However, this is what I meant by starting a new thread for your question. Now you have a solution which other people could be interested in but you cannot mark the thread as [Solved] as it is not yours. Others will probably not find your solution. šŸ˜¢
 
Upvote 0
Top