Forum - MCS Electronics

 

FAQFAQ SearchSearch RegisterRegister Log inLog in

Serial reading problem AVR128DB28

 
Post new topic   Reply to topic    www.mcselec.com Forum Index -> BASCOM-AVR XTINY/MEGAX/AVRX
View previous topic :: View next topic  
Author Message
matjazs

Bascom Member



Joined: 08 Nov 2016
Posts: 100

PostPosted: Sun Feb 02, 2025 2:50 pm    Post subject: Serial reading problem AVR128DB28 Reply with quote

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
View user's profile
oi18ct

Bascom Member



Joined: 08 Mar 2022
Posts: 24
Location: North Branch, Minnesota

usa.gif
PostPosted: Sun Feb 02, 2025 4:23 pm    Post subject: Reply with quote

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
View user's profile Visit poster's website
EDC

Bascom Expert



Joined: 26 Mar 2014
Posts: 1095

poland.gif
PostPosted: Sun Feb 02, 2025 6:29 pm    Post subject: Reply with quote

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 Very Happy 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
View user's profile Visit poster's website
matjazs

Bascom Member



Joined: 08 Nov 2016
Posts: 100

PostPosted: Mon Feb 03, 2025 3:26 pm    Post subject: Reply with quote

Thank you very much. I will try this.
Back to top
View user's profile
EDC

Bascom Expert



Joined: 26 Mar 2014
Posts: 1095

poland.gif
PostPosted: Tue Feb 04, 2025 2:27 pm    Post subject: Reply with quote

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 Wink
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
View user's profile Visit poster's website
matjazs

Bascom Member



Joined: 08 Nov 2016
Posts: 100

PostPosted: Wed Feb 05, 2025 9:40 pm    Post subject: Reply with quote

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
View user's profile
EDC

Bascom Expert



Joined: 26 Mar 2014
Posts: 1095

poland.gif
PostPosted: Thu Feb 06, 2025 10:45 am    Post subject: Reply with quote

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
View user's profile Visit poster's website
Display posts from previous:   
Post new topic   Reply to topic    www.mcselec.com Forum Index -> BASCOM-AVR XTINY/MEGAX/AVRX All times are GMT + 1 Hour
Page 1 of 1

 
Jump to:  
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