View previous topic :: View next topic |
Author |
Message |
matjazs
Joined: 08 Nov 2016 Posts: 100
|
Posted: Sun Feb 02, 2025 2:50 pm Post subject: Serial reading problem AVR128DB28 |
|
|
I am reading data from an energy meter in this format:
Quote: | /ISK5\2M551T-200
0-0:96.1.0(84066279)
0-0:97.97.0(00200000)
1-0:0.9.1(210915)
1-0:0.9.2(250129)
1-0:1.8.0(017079.774*kWh)
1-0:1.8.1(008025.728*kWh)
1-0:1.8.2(009054.046*kWh)
1-0:1.7.0(00.853*kW)
1-0:32.7.0(235.3*V)
1-0:52.7.0(233.9*V)
1-0:72.7.0(237.8*V)
1-0:31.7.0(000*A)
1-0:51.7.0(001*A)
1-0:71.7.0(001*A)
1-0:21.7.0(00.118*kW)
1-0:41.7.0(00.270*kW)
1-0:61.7.0(00.294*kW)
1-0:33.7.0(0.690)
1-0:53.7.0(0.889)
1-0:73.7.0(1.000)
! |
It is sent in a packet, it repeats every 10 seconds.
I would like to read only the data in the brackets. The serial buffer is too small (255).
The data is missing from character 255 onwards because the buffer is too small.
Does anyone have any ideas?
Bascom V. 2.0.8.6 |
|
Back to top |
|
 |
oi18ct
Joined: 08 Mar 2022 Posts: 24 Location: North Branch, Minnesota

|
Posted: Sun Feb 02, 2025 4:23 pm Post subject: |
|
|
I think you are trying to receive all data at once into a single variable since its exceeding 255 chars?
So since each line is less than 255 chars, you could receive and parse the data line by line moving data into holding string vars or an array of string.
In your parser, use the carriage return or line feed (13 or 10) to identify the end of a line. That can be a trigger to parse the data of interest and move it into a holding var. The parentheses (ascii dec 40 and 41) are the logic elements to parse out the data of interest.
bascom has good tools that do most of the heavy lifting- if you haven't already, look at ischarwaiting, memcopy and all the logic operations under Strings in the help file. The samples code will have things you can reference as well _________________ Lee |
|
Back to top |
|
 |
EDC
Joined: 26 Mar 2014 Posts: 1095

|
Posted: Sun Feb 02, 2025 6:29 pm Post subject: |
|
|
Try if this will work since it is not tested. I simply wrote it now.
You have 10 sec period for parse the data so it can be stored in the buffer 512 bytes long for example.
Every received byte prelonge the timeout for parsing the data.
When meter stop sending the data then timeout occur and you can parse.
uC will check for opening bracket and remember where it was. When find the closing bracket then counts the difference betwen start and stop so it can copy the data from Buffer into another buffer but only those bytes betwen the brackets.
This second buffer is an overlay on some Mystring so it can be printed to the second COM port or whatever you want to do with this data.
I hope it will work Good luck
Code: | $regfile = "AVRX128db32.dat"
$crystal = 24000000
$hwstack = 40
$swstack = 40
$framesize = 512
Config Vregpwr = Auto
Config Osc = Enabled , Frequency = 24mhz
Config Sysclock = Int_osc , Prescale = 1
Config Submode = New
Debug On
'*******************************************************
'* CONFIG COM1 BUFFERED USART FOR METER * 'COM1 TXD-PA0-30, RXD-PA1-31 (PA4-26/PA5-27)
'*******************************************************
Config Com1 = 115200 , Mode = Asynchroneous , Parity = None , Databits = 8 , Stopbits = 1
Open "COM1:" For Binary As #1
Config Serialin0 = Buffered , Size = 100
Const Meter = 1
'*******************************************************
'* CONFIG COM2 BUFFERED USART FOR PC * 'COM2 TXD-PC0-6 , RXD-PC1-7 (PC4-14/PC5-17)
'*******************************************************
Config Com2 = 115200 , Mode = Asynchroneous , Parity = None , Databits = 8 , Stopbits = 1
Open "COM2:" For Binary As #2
Config Serialin1 = Buffered , Size = 100
Const Usb = 2
'*******************************************************
'* TIMER SETTINGS FOR TIME BASE *
'*******************************************************
Config Tca0 = Normal , Prescale = 8 , Run = On
Tca0_per = 29999 '10ms @24MHz/8
'*******************************************************
'* PROGRAM VARIABLES *
'*******************************************************
'programm
Dim Buffer(512) As Byte , Idx As Word , Msg_timeout As Byte
Dim N As Word , Start_point As Word , Lenght As Word , Result As Word
Dim Mystring As String * 10
Dim Mybuff(11) As Byte At Mystring Overlay
Enable Interrupts
Debug #usb , "{010}Program started"
Do
If 0 < Ischarwaiting(#meter) Then
If Idx < 512 Then Incr Idx
Buffer(idx) = Inkey(#meter)
Msg_timeout = 50
End If
'-[10ms]-
If Tca0_intflags.tca_single_ovf_bp = 1 Then
Tca0_intflags.tca_single_ovf_bp = 1
If Msg_timeout > 0 Then
Decr Msg_timeout
If Msg_timeout = 0 Then
For N = 1 To Idx
Select Case Buffer(n)
Case 40 : Start_point = N
Case 41
Memfill Mybuff(1) , 11 , 0 'fill with zeros to terminate string
Lenght = N - Start_point
Result = Memcopy(buffer(start_point) , Mybuff(1) , Lenght)
Debug #usb , Mystring 'print to second USART
End Select
Next
Idx = 0 'to be ready for next msg
End If
End If
End If
Loop
End |
This is very simple code. I think some safety routines can be added. _________________ Check B-Flash -my MCS bootloader app for Android (updated) |
|
Back to top |
|
 |
matjazs
Joined: 08 Nov 2016 Posts: 100
|
Posted: Mon Feb 03, 2025 3:26 pm Post subject: |
|
|
Thank you very much. I will try this. |
|
Back to top |
|
 |
EDC
Joined: 26 Mar 2014 Posts: 1095

|
Posted: Tue Feb 04, 2025 2:27 pm Post subject: |
|
|
Sorry. I couldn't resist to test it on the coffe brake.
First I found that second buffer and string is too small because some of the data exeed 10 chars.
Next is to include the closing bracket into the wanted string so "Incr Lenght" is added.
If brackets are unwanted then increase Start_point instead of Lenght (Case 40 : Start_point = N + 1).
Code now works perfectly
I save your data from the Forum in the TXT file (it is 453 byte) and send it over COM1 to the micro with one terminal emulator.
You can watch how data is presented in the second terminal emulator on COM2.
Corrected code below.
Code: | $regfile = "AVRX128db32.dat"
$crystal = 24000000
$hwstack = 40
$swstack = 40
$framesize = 512
Config Vregpwr = Auto
Config Osc = Enabled , Frequency = 24mhz
Config Sysclock = Int_osc , Prescale = 1
Config Submode = New
Debug On
'*******************************************************
'* CONFIG COM1 BUFFERED USART FOR METER * 'COM1 TXD-PA0-30, RXD-PA1-31 (PA4-26/PA5-27)
'*******************************************************
Config Com1 = 115200 , Mode = Asynchroneous , Parity = None , Databits = 8 , Stopbits = 1
Open "COM1:" For Binary As #1
Config Serialin0 = Buffered , Size = 100
Const Meter = 1
'*******************************************************
'* CONFIG COM2 BUFFERED USART FOR PC * 'COM2 TXD-PC0-6 , RXD-PC1-7 (PC4-14/PC5-17)
'*******************************************************
Config Com2 = 115200 , Mode = Asynchroneous , Parity = None , Databits = 8 , Stopbits = 1
Open "COM2:" For Binary As #2
Config Serialin1 = Buffered , Size = 100
Const Usb = 2
'*******************************************************
'* TIMER SETTINGS FOR TIME BASE *
'*******************************************************
Config Tca0 = Normal , Prescale = 8 , Run = On
Tca0_per = 29999 '10ms @24MHz/8
'*******************************************************
'* PROGRAM VARIABLES *
'*******************************************************
'programm
Dim Buffer(512) As Byte , Idx As Word , Msg_timeout As Byte
Dim N As Word , Start_point As Word , Lenght As Word , Result As Word
Dim Mystring As String * 20
Dim Mybuff(21) As Byte At Mystring Overlay
Enable Interrupts
Debug #usb , "{010}Program started"
Do
If 0 < Ischarwaiting(#meter) Then
If Idx < 512 Then Incr Idx
Buffer(idx) = Inkey(#meter)
Msg_timeout = 50
End If
'-[10ms]-
If Tca0_intflags.tca_single_ovf_bp = 1 Then
Tca0_intflags.tca_single_ovf_bp = 1
If Msg_timeout > 0 Then
Decr Msg_timeout
If Msg_timeout = 0 Then
For N = 1 To Idx
Select Case Buffer(n)
Case 40 : Start_point = N
Case 41
Memfill Mybuff(1) , 21 , 0 'fill with zeros to terminate string
Lenght = N - Start_point
Incr Lenght '+1
Result = Memcopy(buffer(start_point) , Mybuff(1) , Lenght)
Debug #usb , Mystring 'print to second USART
End Select
Next
Idx = 0 'to be ready for next msg
End If
End If
End If
Loop
End |
_________________ Check B-Flash -my MCS bootloader app for Android (updated) |
|
Back to top |
|
 |
matjazs
Joined: 08 Nov 2016 Posts: 100
|
Posted: Wed Feb 05, 2025 9:40 pm Post subject: |
|
|
EDC Thank you very much. Your code works OK.
Now I'm trying to add a new array (AD_Buff(20) as string*20) where I want to write the data, but it doesn't work.
Is there a problem with the array declaration or did I something wrong?
This is output:
Quote: | Program started
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
> |
Code:
Code: | $regfile = "AVRX128db28.dat"
$crystal = 24000000
$hwstack = 40
$swstack = 40
$framesize = 512
Config Vregpwr = Auto
Config Osc = Enabled , Frequency = 24mhz
Config Sysclock = Int_osc , Prescale = 1
Config Submode = New
Debug On
'*******************************************************
'* CONFIG COM1 BUFFERED USART FOR METER * 'COM1 TXD-PA0-30, RXD-PA1-31 (PA4-26/PA5-27)
'*******************************************************
Config Com1 = 9600 , Mode = Asynchroneous , Parity = Odd , Stopbits = 1 , Databits = 7
Open "COM1:" For Binary As #1
Config Serialin0 = Buffered , Size = 100
Const Meter = 1
'*******************************************************
'* CONFIG COM2 BUFFERED USART FOR PC * 'COM2 TXD-PC0-6 , RXD-PC1-7 (PC4-14/PC5-17)
'*******************************************************
Config Com2 = 57600 , Mode = Asynchroneous , Parity = None , Databits = 8 , Stopbits = 1
Open "COM2:" For Binary As #2
Config Serialin1 = Buffered , Size = 100
Const Usb = 2
'*******************************************************
'* TIMER SETTINGS FOR TIME BASE *
'*******************************************************
Config Tca0 = Normal , Prescale = 8 , Run = On
Tca0_per = 29999 '10ms @24MHz/8
'*******************************************************
'* PROGRAM VARIABLES *
'*******************************************************
'programm
Dim Buffer(512) As Byte , Idx As Word , Msg_timeout As Byte
Dim N As Word , Start_point As Word , Lenght As Word , Result As Word
Dim Mystring As String * 20
Dim Mybuff(21) As Byte At Mystring Overlay
Dim Am_buff(20) As String * 20 ' Array for text
Dim I As Byte
Enable Interrupts
Debug #usb , "{010}Program started"
Do
If 0 < Ischarwaiting(#meter) Then
If Idx < 512 Then Incr Idx
Buffer(idx) = Inkey(#meter)
Msg_timeout = 50
End If
'-[10ms]-
If Tca0_intflags.tca_single_ovf_bp = 1 Then
Tca0_intflags.tca_single_ovf_bp = 1
If Msg_timeout > 0 Then
Decr Msg_timeout
If Msg_timeout = 0 Then
For N = 1 To Idx
Select Case Buffer(n)
Case 40 : Start_point = N
Case 41
Memfill Mybuff(1) , 21 , 0 'fill with zeros to terminate string
Lenght = N - Start_point
Incr Lenght '+1
Result = Memcopy(buffer(start_point) , Mybuff(1) , Lenght)
'Debug #usb , Mystring 'print to second USART
Am_buff(n) = Mystring
End Select
Next
Gosub Wr_data 'Write data to port
Idx = 0 'to be ready for next msg
End If
End If
End If
Loop
End
'---------------------------------------------------
Wr_data:
For I = 1 To 21
Print #usb , "> " ; Am_buff(i)
Next
Return |
|
|
Back to top |
|
 |
EDC
Joined: 26 Mar 2014 Posts: 1095

|
Posted: Thu Feb 06, 2025 10:45 am Post subject: |
|
|
You cannot use variable N for point Am_buff() table. You must declare another
Code: | Dim Idx2 As byte
If Idx2 < 20 Then Incr Idx2
Am_buff(Idx2) = Mystring
'and after For-Next loop
Idx = 0 : Idx2 = 0 'so on next parsing, after Incr, we start from Idx2 = 1
|
And after all "For I = 1 to 20" I think. Not 21
I like to work on some program constants because I can use it in many code cases and they are always keep the track about my declarations.
For example:
Code: | Const MyStrArrayLen = 20
Dim Am_buff(MyStrArrayLen) As String *20
If Idx2 < MyStrArrayLen Then Incr Idx2
For I = 1 to Idx2 'because it never exeed 20
'do something
Next
|
I can easly change one Constant for increase/decrease size of that array of strings but I dont need to check my whole code. _________________ Check B-Flash -my MCS bootloader app for Android (updated) |
|
Back to top |
|
 |
|
|
You can post new topics in this forum You can reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum You cannot attach files in this forum You cannot download files in this forum
|
|