B4R Question Read Error from main variables

Tayfur

Well-Known Member
Licensed User
Longtime User
Hello;
I declred verables in main.
After I call this variables on usermodule.
I read an error on log. Where is the problem?

I checked values
WiFiServer.Read32(1)>>> "-"
WiFiServer.Read32(1)>>> "-"

MAIN CODE
B4X:
Sub Process_Globals
 
     
    Public Const C_AP_user As String="Default_AP_for_ARDUINO"
    Public Const C_AP_pass As String="12345678"
    Public Const C_Host_datetime As String="kartektube.com"
    Public Const C_Host_gets_datetime As String="/datetime.asp"
    Public Const C_KartekWifi_User As String="KARTEK2"
    Public Const C_KartekWifi_Pass As String="kartek6161"
    Public Merkez_wifi(2) As String
    Public Makine(2) As String
    Public Sensor_Kapi As Boolean
    Public Sensor_Motor As Boolean
    Public Sensor_Sayac As Boolean
end sub

Private Sub AppStart
 
    Serial1.Initialize(115200)
    Log("AppStart")
    ww=True
    Log("step1")
 
    Log("Eeprom size:",eeprom.size)
    eeprom.WriteBytes(bc.StringToBytes("tayfur"),4000)
    Log("kayıt")
    Merkez_wifi(0) = (WiFiServer.ReadSSID)
    Log("****1****   ",Merkez_wifi(0))
    Merkez_wifi(1) = (WiFiServer.ReadPassword)
    Log("****2****   ",Merkez_wifi(1))
    Makine(0)=WiFiServer.Read32(1)
    Log("****3****   ",Makine(0))
    Makine(1)=WiFiServer.Read32(2)
    Log("****4****   ",Makine(1))
    If WiFiServer.Read32(2)="T" Then Sensor_Kapi=True Else Sensor_Kapi=False
    If WiFiServer.Read32(3)="T" Then Sensor_Motor=True Else Sensor_Motor=False
    If WiFiServer.Read32(4)="T" Then Sensor_Sayac=True Else Sensor_Sayac=False
end sub

USER MODULE >> WifiServer
B4X:
Private sub logs
   Log(">>>>>>>>>1",Main.Makine(0))
end sub
Public Sub Read32(StartPositon As Int) As String
    Dim x As String ="-"
    Dim header() As Byte = eeprom.ReadBytes(StartPositon*32, 2)
    If header(0) = MAGIC_EEPROM Then
        Dim data() As Byte = eeprom.ReadBytes(StartPositon*32+2, header(1))
    x = bc.StringFromBytes(data)'(bc.SubString2(data, 0, i))
    Else
        Log("Network data not found.")
        x="-"
    End If
    Return x
End Sub

Public Sub Write32(data As String,StartPositon As Int) As Boolean
    If data.Length>30 Then Return False
    eeprom.WriteBytes(Array As Byte(MAGIC_EEPROM,data.Length),StartPositon*32)
    eeprom.WriteBytes(data,StartPositon*32+2)
    Return True
End Sub

>>>>>>>>>1
Exception (28):
epc1=0x4000bf70 epc2=0x00000000 epc3=0x00000000 excvaddr=0x0a0d312c depc=0x00000000
ctx: cont
sp: 3ffefa50 end: 3fff0180 offset: 01a0
>>>stack>>>
3ffefbf0: 3ffefc90 3ffefc70 00000004 00000001
3ffefc00: 0a0d312e 3ffefc60 402091bc 3ffef160
3ffefc10: 3ffefc50 00000009 00000001 40208ae0
3ffefc20: 3ffef09c 00000002 00000000 40202745
3ffefc30: 3ffefc40 00000002 00000001 4020235f
3ffefc40: 4023662c 00000066 0a0d312e 40202365
3ffefc50: 3ffeed98 00000002 00000000 40209472
3ffefc60: 3ffefc90 3ffefc70 00000004 feefeffe
3ffefc70: feefeffe 00000066 4023662c 00000065
3ffefc80: 0a0d312e 3ffe85c2 3ffeeeb8 40201ec3
 
Last edited:

Tayfur

Well-Known Member
Licensed User
Longtime User
This line is wrong:
B4X:
Makine(0)=WiFiServer.Read32(1)

To tell you the exact problem we need to see the implementation of WiFiServer.Read32.

i think, its has not a problem!!!
B4X:
' proceess Global added EEPROM lib
Public Sub Read32(StartPositon As Int) As String
    Dim x As String ="-"
    Dim header() As Byte = eeprom.ReadBytes(StartPositon*32, 2)
    If header(0) = MAGIC_EEPROM Then
        Dim data() As Byte = eeprom.ReadBytes(StartPositon*32+2, header(1))
    x = bc.StringFromBytes(data)'(bc.SubString2(data, 0, i))
    Else
        Log("Network data not found.")
        x="-"
    End If
    Return x
End Sub

Public Sub Write32(data As String,StartPositon As Int) As Boolean
    If data.Length>30 Then Return False
    eeprom.WriteBytes(Array As Byte(MAGIC_EEPROM,data.Length),StartPositon*32)
    eeprom.WriteBytes(data,StartPositon*32+2)
    Return True
End Sub
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
It is the problem.

You are creating a dynamic string on the stack. The string memory is released once the Read32 sub ends.

The correct way to move the result to the heap (global variable) is:
1. Don't use an array of strings. Create two arrays of bytes that are large enough to hold the values.
2. Copy the data with:
B4X:
bc.ArrayCopy(data, Main.Makine1)
 
Upvote 0

Tayfur

Well-Known Member
Licensed User
Longtime User
It is the problem.

You are creating a dynamic string on the stack. The string memory is released once the Read32 sub ends.

The correct way to move the result to the heap (global variable) is:
1. Don't use an array of strings. Create two arrays of bytes that are large enough to hold the values.
2. Copy the data with:
B4X:
bc.ArrayCopy(data, Main.Makine1)

Sorry @Erel; dont work. ( I know, this not pc or android)

I added full code. Please check it.

"MAIN" block

B4X:
#Region Project Attributes
    #AutoFlushLogs: True
    #CheckArrayBounds: True
    #StackBufferSize: 300
#End Region

Sub Process_Globals
    'These global variables will be declared once when the application starts.
    'Public variables can be accessed from all modules.
    Public Serial1 As Serial
    Public Merkez_wifi(2) As String
    Public Makine(2) As String
    Public Makine1() As Byte
    Public Makine2() As Byte
    Private bc As ByteConverter
    Private eeprom As EEPROM ' kapasiteyi değiştirmek için C:\..\B4R\Libraries\rEEPROM\rEEPROM.cpp (line 14). >>> EEPROM.begin(4096);
    Private const MAGIC_EEPROM As Byte = 123
    Private timers As Timer
End Sub

Private Sub AppStart
    Serial1.Initialize(115200)
    Log("AppStart")
    WifiServer.Write32("Sample data1",1)
    WifiServer.Write32("other sapmle2",2)
    timers.Initialize("timers_Tick",5000)
    timers.Enabled=True
    Log("timer started")
  
  
End Sub

Private Sub timers_Tick
    bc.ArrayCopy(WifiServer.Read32(1), Makine1)
    Log("****3****   ",Makine1)
    bc.ArrayCopy(WifiServer.Read32(2), Makine2)
    Log("****4****   ",Makine2)
  
    WifiServer.logs
End Sub

"WifiServer" Block
B4X:
Sub Process_Globals
    'These global variables will be declared once when the application starts.
    'Public variables can be accessed from all modules.
    Private eeprom As EEPROM ' kapasiteyi değiştirmek için C:\..\B4R\Libraries\rEEPROM\rEEPROM.cpp (line 14). >>> EEPROM.begin(4096);
    Private const MAGIC_EEPROM As Byte = 123
    Private bc As ByteConverter
End Sub

Public Sub logs
   Log(">>>>>>>>>1",Main.Makine1)
    Log(">>>>>>>>>2",Main.Makine1)
End Sub

Public Sub Read32(StartPositon As Int) As Byte()
    Dim x() As Byte ="-"
    Dim header() As Byte = eeprom.ReadBytes(StartPositon*32, 2)
    If header(0) = MAGIC_EEPROM Then
        Dim data() As Byte = eeprom.ReadBytes(StartPositon*32+2, header(1))
    x = data'bc.StringFromBytes(data)'(bc.SubString2(data, 0, i))
    Log("Resad32> ", eeprom.ReadBytes(StartPositon*32, 32))
    Else
        Log("Network data not found.")
        x=bc.StringToBytes("-")
    End If
    Return x
End Sub

Public Sub Write32(data As String,StartPositon As Int) As Boolean
    If data.Length>30 Then Return False
    eeprom.WriteBytes(Array As Byte(MAGIC_EEPROM,data.Length),StartPositon*32)
    eeprom.WriteBytes(data,StartPositon*32+2)
    Return True
End Sub
 
Upvote 0

Tayfur

Well-Known Member
Licensed User
Longtime User
sorry @Erel; I tried alot of ways.

Basicly;

1.... I want using all modules same string variables.
And
2.... I want to read write eeprom from this variables. I used samples in forum.
-----------------------------------
write 1.data with write32 sub
write 2.data with write32 sub
reset board.
read 1.data with read32 sub >> result is not correct.
read 2.data with read32 sub >> result is correct.

this is very interesting!! ı cant understand :(
 
Last edited:
Upvote 0

Tayfur

Well-Known Member
Licensed User
Longtime User
Use File - Export as zip.
Hello @Erel;
I added my project.

Steps:
  1. Run my project.
  2. Wemos starting AP moode. And connect it (to card)
  3. ip is 192.168.4.1
  4. Chrome open and call 192.168.4.1/info
  5. Please look logs(Programm broken), each time changed results ????
    1. "WifiServer" Module on lines 190-260; problem lines with logs.
    2. not show all lines on web browser
-------------------------------------------------------------
Other issue

"192.168.4.1/info" results is for my records.
I added new record with
"http://192.168.4.1/merkezwifiset/KARTEK12/kartek61612"
after cheked with info
"192.168.4.1/info"
I looked my KArtek12 and kartek61612

After i added other record
"http://192.168.4.1/makineset/M03/dairetestere"
and cheked it with info
"192.168.4.1/info"
i looked my records "M03" and "dairetestre"
I looked my records "KArtek12 " and "kartek61612"

After I reset card.
Connect again
cheked rekords with info
"192.168.4.1/info"
i looked my records "M03" and "dairetestre"
I dont looked my records "- " and "-"
But; I cant erase it.
 

Attachments

  • test.zip
    7.6 KB · Views: 300
Last edited:
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
I've only tested the EEPROM reading and writing code.

I've changed AppStart to:
B4X:
Private Sub AppStart
   
   Serial1.Initialize(115200)
   Log("AppStart")
   ww=True
   Log("step1")
   Log("Eeprom size:",eeprom.size)
   Log("kayıt")
   WiFiServer.Read32(3)
   WiFiServer.Read32(4)
   Log("****1****  ",Merkez_wifi_SSID)
   Log("****2****  ",Merkez_wifi_Pass)
   WiFiServer.Read32(1)
   Log("****3****  ",Makine1," :",Makine1.Length)
   WiFiServer.Read32(2)
   Log("****4****  ",Makine2," :",Makine2.Length)
   WiFiServer.Write32("data_1", 1)
   WiFiServer.Write32("data_2", 2)
   WiFiServer.Write32("data_3", 3)
   WiFiServer.Write32("data_4", 4)
   
End Sub

I've cleaned WifiServer.Read32:
B4X:
Public Sub Read32(StartPositon As Int) As Boolean
   Log("***Public Sub Read32")
   Dim header() As Byte = eeprom.ReadBytes(StartPositon*32, 2)
   If header(0) = MAGIC_EEPROM Then
     Dim data() As Byte = eeprom.ReadBytes(StartPositon*32+2, header(1))
   Else
     Log("Network data not found.")
     data = "-"
   End If
   Select StartPositon
     Case 1
       bc.ArrayCopy(data, Main.Makine1)
     Case 2
       bc.ArrayCopy(data, Main.Makine2)
     Case 3
       bc.ArrayCopy(data, Main.Merkez_wifi_SSID)
     Case 4
       bc.ArrayCopy(data, Main.Merkez_wifi_Pass)
     Case Else
       Return False
   End Select
   Return True
End Sub

It works properly.
 
Upvote 0

Tayfur

Well-Known Member
Licensed User
Longtime User
I've only tested the EEPROM reading and writing code.

I've changed AppStart to:
B4X:
Private Sub AppStart
  
   Serial1.Initialize(115200)
   Log("AppStart")
   ww=True
   Log("step1")
   Log("Eeprom size:",eeprom.size)
   Log("kayıt")
   WiFiServer.Read32(3)
   WiFiServer.Read32(4)
   Log("****1****  ",Merkez_wifi_SSID)
   Log("****2****  ",Merkez_wifi_Pass)
   WiFiServer.Read32(1)
   Log("****3****  ",Makine1," :",Makine1.Length)
   WiFiServer.Read32(2)
   Log("****4****  ",Makine2," :",Makine2.Length)
   WiFiServer.Write32("data_1", 1)
   WiFiServer.Write32("data_2", 2)
   WiFiServer.Write32("data_3", 3)
   WiFiServer.Write32("data_4", 4)
  
End Sub

I've cleaned WifiServer.Read32:
B4X:
Public Sub Read32(StartPositon As Int) As Boolean
   Log("***Public Sub Read32")
   Dim header() As Byte = eeprom.ReadBytes(StartPositon*32, 2)
   If header(0) = MAGIC_EEPROM Then
     Dim data() As Byte = eeprom.ReadBytes(StartPositon*32+2, header(1))
   Else
     Log("Network data not found.")
     data = "-"
   End If
   Select StartPositon
     Case 1
       bc.ArrayCopy(data, Main.Makine1)
     Case 2
       bc.ArrayCopy(data, Main.Makine2)
     Case 3
       bc.ArrayCopy(data, Main.Merkez_wifi_SSID)
     Case 4
       bc.ArrayCopy(data, Main.Merkez_wifi_Pass)
     Case Else
       Return False
   End Select
   Return True
End Sub

It works properly.
thank you ,@Erel ;

I will test it.
 
Upvote 0
Top