B4R Question Appstart repeating in logs

ilan

Expert
Licensed User
Longtime User
hi

if the "Appstart" is constantly repeating in the logs does it means i have low memory left and app is always restarting?
i am using a Arduino uno with 3 stepper motors and an LED screen + bluetooth and it looks like all libraries enabled + some global variables does not leave enough memory for the board to oporate. can that be? what could be the solution? switching to arduino mega?

i need to mention that i have not even started with all the function i want to implement and i am not sure the mega will be also enough for it. i guess i am doing something completly wrong.
i have very small experience with working with bytes but i can see that JOINSTRING and converting everything to strings takes a lot memory but cannot figure out how to work with bytes to keep the memory low.

libraries i use:

1656059468402.png


logs:

Loading configuration...
Initializing packages...
Preparing boards...
Verifying...
...
Linking everything together...
"C:\\Arduino\\hardware\\tools\\avr/bin/avr-gcc" -Os -g -flto -fuse-linker-plugin -Wl,--gc-sections -mmcu=atmega328p -o "C:\\wbm\\B4R\\Objects\\bin/src.ino.elf" "C:\\wbm\\B4R\\Objects\\bin\\sketch\\glcdfont.c.o" "C:\\wbm\\B4R\\Objects\\bin\\sketch\\Adafruit_GFX.cpp.o" "C:\\wbm\\B4R\\Objects\\bin\\sketch\\Adafruit_SSD1306.cpp.o" "C:\\wbm\\B4R\\Objects\\bin\\sketch\\AsyncStreams.cpp.o" "C:\\wbm\\B4R\\Objects\\bin\\sketch\\B4RArduino.cpp.o" "C:\\wbm\\B4R\\Objects\\bin\\sketch\\B4RCore.cpp.o" "C:\\wbm\\B4R\\Objects\\bin\\sketch\\B4RSerializator.cpp.o" "C:\\wbm\\B4R\\Objects\\bin\\sketch\\B4RStream.cpp.o" "C:\\wbm\\B4R\\Objects\\bin\\sketch\\ByteConverter.cpp.o" "C:\\wbm\\B4R\\Objects\\bin\\sketch\\RandomAccessFile.cpp.o" "C:\\wbm\\B4R\\Objects\\bin\\sketch\\Scheduler.cpp.o" "C:\\wbm\\B4R\\Objects\\bin\\sketch\\b4r_main.cpp.o" "C:\\wbm\\B4R\\Objects\\bin\\sketch\\rAdafruitGFX.cpp.o" "C:\\wbm\\B4R\\Objects\\bin\\sketch\\rAdafruitSSD1306.cpp.o" "C:\\wbm\\B4R\\Objects\\bin\\sketch\\rSoftwareSerial.cpp.o" "C:\\wbm\\B4R\\Objects\\bin\\sketch\\rStepper.cpp.o" "C:\\wbm\\B4R\\Objects\\bin\\sketch\\src.ino.cpp.o" "C:\\wbm\\B4R\\Objects\\bin\\libraries\\SoftwareSerial\\SoftwareSerial.cpp.o" "C:\\wbm\\B4R\\Objects\\bin\\libraries\\SPI\\SPI.cpp.o" "C:\\wbm\\B4R\\Objects\\bin\\libraries\\Stepper\\Stepper.cpp.o" "C:\\wbm\\B4R\\Objects\\bin\\libraries\\Wire\\Wire.cpp.o" "C:\\wbm\\B4R\\Objects\\bin\\libraries\\Wire\\utility\\twi.c.o" "C:\\wbm\\B4R\\Objects\\bin/core\\core.a" "-LC:\\wbm\\B4R\\Objects\\bin" -lm
"C:\\Arduino\\hardware\\tools\\avr/bin/avr-objcopy" -O ihex -j .eeprom --set-section-flags=.eeprom=alloc,load --no-change-warnings --change-section-lma .eeprom=0 "C:\\wbm\\B4R\\Objects\\bin/src.ino.elf" "C:\\wbm\\B4R\\Objects\\bin/src.ino.eep"
"C:\\Arduino\\hardware\\tools\\avr/bin/avr-objcopy" -O ihex -R .eeprom "C:\\wbm\\B4R\\Objects\\bin/src.ino.elf" "C:\\wbm\\B4R\\Objects\\bin/src.ino.hex"
Using library SoftwareSerial at version 1.0 in folder: C:\Arduino\hardware\arduino\avr\libraries\SoftwareSerial
Using library SPI at version 1.0 in folder: C:\Arduino\hardware\arduino\avr\libraries\SPI
Using library Stepper at version 1.1.3 in folder: C:\Arduino\libraries\Stepper
Using library Wire at version 1.0 in folder: C:\Arduino\hardware\arduino\avr\libraries\Wire
"C:\\Arduino\\hardware\\tools\\avr/bin/avr-size" -A "C:\\wbm\\B4R\\Objects\\bin/src.ino.elf"
Sketch uses 21624 bytes (67%) of program storage space. Maximum is 32256 bytes.
Global variables use 1545 bytes (75%) of dynamic memory, leaving 503 bytes for local variables. Maximum is 2048 bytes.
Low memory available, stability problems may occur.
Uploading...
********************* PROGRAM STARTING ****************
AppStart
AppStart
AppStart
AppStart
AppStart
AppStart
AppStart
AppStart
AppStart
AppStart
AppStart
AppStart
AppStart
AppStart
AppStart
AppStart
AppStart
AppStart
AppStart
AppStart
AppStart
AppStart
AppStart
AppStart
AppStart
...
 

janderkan

Well-Known Member
Licensed User
Longtime User
I will give you an example with the same result.
B4X:
Dim T as timer

T.interval=1000
T.Enabled=True
 
Upvote 0

ilan

Expert
Licensed User
Longtime User
I will give you an example with the same result.
B4X:
Dim T as timer

T.interval=1000
T.Enabled=True

i dont understand what you mean
 
Upvote 0

RJB

Active Member
Licensed User
Longtime User
The first thing to try, always, is increasing the stack buffer (I currently have mine increased to 5500):
B4X:
#Region Project Attributes
    #AutoFlushLogs: True
    #CheckArrayBounds: True
    #StackBufferSize:  5500
    'https://www.b4x.com/android/forum/threads/resp8266filesystem-spiffs.76487/
    #DefineExtra: #define SKIP_B4RNEW
#End Region
Note: this is on as esp32 system so has more memory available!
 
Last edited:
Upvote 0

RJB

Active Member
Licensed User
Longtime User
You can check buffer usage and available RAM with:
B4X:
Log(StackBufferUsage, " : ", AvailableRAM)
I'm also not sure why that timer code would cause restarts, although no '_tick' sub is shown.
 
Upvote 0

janderkan

Well-Known Member
Licensed User
Longtime User
i dont understand what you mean
This code will make your unit restart again and again.
You will see Appstart repeatedly in the log.
The reason is that the Timer object is not initialized.
So I was trying to tell you to check your code.
 
Upvote 0

ilan

Expert
Licensed User
Longtime User
The first thing to try, always, is increasing the stack buffer (I currently have mine increased to 5500):
B4X:
#Region Project Attributes
    #AutoFlushLogs: True
    #CheckArrayBounds: True
    #StackBufferSize:  5500
    'https://www.b4x.com/android/forum/threads/resp8266filesystem-spiffs.76487/
    #DefineExtra: #define SKIP_B4RNEW
#End Region
i guess u r using arduino mega because uno has only 2kb sram

You can check buffer usage and available RAM with:
B4X:
Log(StackBufferUsage, " : ", AvailableRAM)
I'm also not sure why that timer code would cause restarts, although no '_tick' sub is shown.

this is what i have:
0 : 327

This code will make your unit restart again and again.
You will see Appstart repeatedly in the log.
The reason is that the Timer object is not initialized.
So I was trying to tell you to check your code.
ok now i understand what you mean but there is nothing wrong with my code
what i think is that there is not enough memory
 
Upvote 0

ilan

Expert
Licensed User
Longtime User
B4X:
#Region Project Attributes
    #AutoFlushLogs: True
    #CheckArrayBounds: True
    #StackBufferSize: 290
#End Region

Sub Process_Globals
    Public Serial1 As Serial
    Private SoftwareSerial1 As SoftwareSerial 'ignore
    Private astream As AsyncStreams 'ignore
    Private zMotor, cMotor, aMotor As Stepper 'ignore
    Private StepsPerRevolution As Int = 200 'ignore
    Private ssd As AdafruitSSD1306
    Private Timer1 As Timer 'ignore
    Private APin As Pin 'ignore
    Private degStep As Float = StepsPerRevolution/360 'ignore
    Private gcodeArr(10) As String
    Private gcodeLast As Int
End Sub

Private Sub AppStart
    Serial1.Initialize(115200)
    Log("AppStart")
    
    'initialize Z-Motor (wire pusher)
    zMotor.Initialize2(StepsPerRevolution, 4, 5, 6, 7)
    zMotor.SetSpeed(60)
    
    'initialize C-Motor (gear controller)
    cMotor.Initialize2(StepsPerRevolution, 8, 9, 10, 11)
    cMotor.SetSpeed(60)
    
    'initialize A-Motor (bender)
    aMotor.Initialize2(StepsPerRevolution, 2, 3, 12, 13)
    aMotor.SetSpeed(60)

    SoftwareSerial1.Initialize(9600, APin.A0, APin.A1)
    astream.Initialize(SoftwareSerial1.Stream, "astream_NewData", Null)
    Timer1.Initialize("timer1_Tick", 1000)
    Timer1.Enabled = True

    ssd.InitializeI2C(4, 0x3c)
    drawscreen("Loading...","","","")
    CallSubPlus("startgcode",1000,0)
    
    Log(StackBufferUsage, " : ", AvailableRAM)
End Sub

Sub startgcode(b() As Byte)
'    Dim bc As ByteConverter
    Dim gcode() As Byte = "P0001,720/0/0,0/0/180,0/0/-180,680/0/0,0/0/180,0/0/-180,760/0/0,M2"
    testGcode(gcode)
End Sub

Sub drawscreen(line1 As String, line2 As String, line3 As String, line4 As String)
    ssd.ClearDisplay
    ssd.GFX.SetCursor(0,0)
    ssd.GFX.DrawText(line1)
    ssd.GFX.SetCursor(0,8)
    ssd.GFX.DrawText(line2)
    ssd.GFX.SetCursor(0,16)
    ssd.GFX.DrawText(line3)
    ssd.GFX.SetCursor(0,24)
    ssd.GFX.DrawText(line4)
    ssd.Display
End Sub
'
Sub testGcode(b() As Byte)
    'Z-Axis (Wire pusher) Pos1
    'C-Axis (Gear control) Pos2
    'A-Axis (Bender Control) Pos3
    gcodeLast = 0
    Dim AxisStep(3) As String
    Dim bc As ByteConverter
    For Each s0() As Byte In bc.Split(b, ",")
        If bc.IndexOf(s0,"/") > -1 Then
            Dim count As Int = 0
            For Each s1() As Byte In bc.Split(s0,"/")
                AxisStep(count) = bc.StringFromBytes(s1)
                count = count + 1
            Next
            'Dim line() As Byte = "test"' JoinStrings(Array As String( "Z",AxisStep(0), " C",AxisStep(1)," A",AxisStep(2)))
            gcodeArr(gcodeLast) = JoinStrings(Array As String( "Z",AxisStep(0), " C",AxisStep(1)," A",AxisStep(2)))
'            If lines(1).Length = 0 Then
'                lines(1) = line
'            else if lines(2).Length = 0 Then
'                lines(2) = line
'            Else if lines(3).Length = 0 Then
'                lines(3) = line
'            Else
'                lines(0) = lines(1)
'                lines(1) = lines(2)
'                lines(2) = lines(3)
'                lines(3) = line
'            End If
            'drawscreen(lines(0),lines(1),lines(2),lines(3))
        Else
            gcodeArr(gcodeLast) = bc.StringFromBytes(s0)
'            If bc.IndexOf(s0,"P") > -1 Then
            'lines(0) = bc.StringFromBytes(s0)
            'drawscreen(lines(0),lines(1),lines(2),lines(3))
'            Else
'                If lines(1).Length = 0 Then
'                    lines(1) = bc.StringFromBytes(s0)
'                else if lines(2).Length = 0 Then
'                    lines(2) = bc.StringFromBytes(s0)
'                Else if lines(3).Length = 0 Then
'                    lines(3) = bc.StringFromBytes(s0)
'                Else
'                    lines(0) = lines(1)
'                    lines(1) = lines(2)
'                    lines(2) = lines(3)
'                    lines(3) = bc.StringFromBytes(s0)
'                End If
'                drawscreen(lines(0),lines(1),lines(2),lines(3))
'            End If
        End If
        gcodeLast = gcodeLast + 1
    Next
    
    Log("gcode length: ", gcodeLast)
    Log("finished")
End Sub
 
'Sub Step1(u As Byte)
'    For i = 0 To StepsPerRevolution
'        zMotor.Step(direction)
'        aMotor.Step(direction)
'    Next
'    direction = direction * -1
'    CallSubPlus("Step1", 1000, 0)
'End Sub

Sub Timer1_Tick
    astream.Write("Millis here: ".GetBytes)
    astream.Write(NumberFormat(Millis, 0, 0).GetBytes)
    astream.Write(Array As Byte(10)) 'end of line character. AsyncStreamsText will cut the message here
End Sub
'
Sub astream_NewData (Buffer() As Byte)
    Dim bc As ByteConverter
    Dim value As String = bc.StringFromBytes(Buffer)
    Select value
        Case "AUP"
            aMotor.Step(10)
        Case "AD"
            aMotor.Step(-10)
        Case "ZUP"
            zMotor.Step(10)
        Case "ZD"
            zMotor.Step(-10)
        Case "CUP"
            cMotor.Step(10)
        Case "CD"
            cMotor.Step(-10)
    End Select
End Sub
 
Last edited:
Upvote 0

janderkan

Well-Known Member
Licensed User
Longtime User
B4X:
#Region Project Attributes
    #AutoFlushLogs: True
    #CheckArrayBounds: True
    #StackBufferSize: 1000
#End Region

Sub Process_Globals
    Public Serial1 As Serial
    Private SoftwareSerial1 As SoftwareSerial 'ignore
    Private astream As AsyncStreams 'ignore
    Private zMotor, cMotor, aMotor As Stepper 'ignore
    Private StepsPerRevolution As Int = 200 'ignore
    Private ssd As AdafruitSSD1306
    Private Timer1 As Timer 'ignore
    Private APin As Pin 'ignore
'    Private degStep As Float = StepsPerRevolution/360 'ignore
    Private gcodeArr(10) As String
    Private gcodeLast As Int
End Sub

Private Sub AppStart
    Serial1.Initialize(115200)
    Log("AppStart")
   
    'initialize Z-Motor (wire pusher)
    zMotor.Initialize2(StepsPerRevolution, 4, 5, 6, 7)
    zMotor.SetSpeed(60)
   
    'initialize C-Motor (gear controller)
    cMotor.Initialize2(StepsPerRevolution, 8, 9, 10, 11)
    cMotor.SetSpeed(60)
   
    'initialize A-Motor (bender)
    aMotor.Initialize2(StepsPerRevolution, 2, 3, 12, 13)
    aMotor.SetSpeed(60)

    SoftwareSerial1.Initialize(9600, APin.A0, APin.A1)
    astream.Initialize(SoftwareSerial1.Stream, "astream_NewData", Null)
    Timer1.Initialize("timer1_Tick", 1000)
    Timer1.Enabled = True

    Log(StackBufferUsage, " : ", AvailableRAM)
 
    ssd.InitializeI2C(4, 0x3c)
    drawscreen("Loading...","","","")
    CallSubPlus("startgcode",1000,"")
End Sub

Sub startgcode(b() As Byte)
'    Dim bc As ByteConverter
    Dim gcode() As Byte = "P0001,720/0/0,0/0/180,0/0/-180,680/0/0,0/0/180,0/0/-180,760/0/0,M2"
    testGcode(gcode)
End Sub

Sub drawscreen(line1 As String, line2 As String, line3 As String, line4 As String)
    ssd.ClearDisplay
    ssd.GFX.SetCursor(0,0)
    ssd.GFX.DrawText(line1)
    ssd.GFX.SetCursor(0,8)
    ssd.GFX.DrawText(line2)
    ssd.GFX.SetCursor(0,16)
    ssd.GFX.DrawText(line3)
    ssd.GFX.SetCursor(0,24)
    ssd.GFX.DrawText(line4)
    ssd.Display
End Sub
'
Sub testGcode(b() As Byte)
    'Z-Axis (Wire pusher) Pos1
    'C-Axis (Gear control) Pos2
    'A-Axis (Bender Control) Pos3
    gcodeLast = 0
    Dim AxisStep(3) As String
    Dim bc As ByteConverter
    For Each s0() As Byte In bc.Split(b, ",")
        If bc.IndexOf(s0,"/") > -1 Then
            Dim count As Int = 0
            For Each s1() As Byte In bc.Split(s0,"/")
                AxisStep(count) = bc.StringFromBytes(s1)
                count = count + 1
            Next
            'Dim line() As Byte = "test"' JoinStrings(Array As String( "Z",AxisStep(0), " C",AxisStep(1)," A",AxisStep(2)))
            gcodeArr(gcodeLast) = JoinStrings(Array As String( "Z",AxisStep(0), " C",AxisStep(1)," A",AxisStep(2)))
'            If lines(1).Length = 0 Then
'                lines(1) = line
'            else if lines(2).Length = 0 Then
'                lines(2) = line
'            Else if lines(3).Length = 0 Then
'                lines(3) = line
'            Else
'                lines(0) = lines(1)
'                lines(1) = lines(2)
'                lines(2) = lines(3)
'                lines(3) = line
'            End If
            'drawscreen(lines(0),lines(1),lines(2),lines(3))
        Else
            gcodeArr(gcodeLast) = bc.StringFromBytes(s0)
'            If bc.IndexOf(s0,"P") > -1 Then
            'lines(0) = bc.StringFromBytes(s0)
            'drawscreen(lines(0),lines(1),lines(2),lines(3))
'            Else
'                If lines(1).Length = 0 Then
'                    lines(1) = bc.StringFromBytes(s0)
'                else if lines(2).Length = 0 Then
'                    lines(2) = bc.StringFromBytes(s0)
'                Else if lines(3).Length = 0 Then
'                    lines(3) = bc.StringFromBytes(s0)
'                Else
'                    lines(0) = lines(1)
'                    lines(1) = lines(2)
'                    lines(2) = lines(3)
'                    lines(3) = bc.StringFromBytes(s0)
'                End If
'                drawscreen(lines(0),lines(1),lines(2),lines(3))
'            End If
        End If
        gcodeLast = gcodeLast + 1
    Next
   
    Log("gcode length: ", gcodeLast)
   
'    For i = 0 To gcodeLast
'        Log(gcodeArr(i))
'    Next
    Log("finished")
End Sub
 
'Sub Step1(u As Byte)
'    For i = 0 To StepsPerRevolution
'        zMotor.Step(direction)
'        aMotor.Step(direction)      
'    Next
'    direction = direction * -1
'    CallSubPlus("Step2", 1000, 0)
'End Sub
'
'Sub Step2(u As Byte)
'    cMotor.Step((StepsPerRevolution/4)*direction)
'    CallSubPlus("Step1", 1000, 0)
'End Sub

Sub Timer1_Tick
    astream.Write("Millis here: ".GetBytes)
    astream.Write(NumberFormat(Millis, 0, 0).GetBytes)
    astream.Write(Array As Byte(10)) 'end of line character. AsyncStreamsText will cut the message here
End Sub
'
Sub astream_NewData (Buffer() As Byte)
    Dim bc As ByteConverter
    Dim value As String = bc.StringFromBytes(Buffer)
    Select value
        Case "AUP"
            aMotor.Step(10)
        Case "AD"
            aMotor.Step(-10)
        Case "ZUP"
            zMotor.Step(10)
        Case "ZD"
            zMotor.Step(-10)
        Case "CUP"
            cMotor.Step(10)
        Case "CD"
            cMotor.Step(-10)
    End Select
End Sub
 
Upvote 0

janderkan

Well-Known Member
Licensed User
Longtime User
You must find the exact line that makes the unit restart
Just comment all out and uncomment one line at a time
 
Upvote 0

ilan

Expert
Licensed User
Longtime User
You must find the exact line that makes the unit restart
Just comment all out and uncomment one line at a time
i tried it and from what i see is that if i comment all steppers initialize it work because i have more memory and i i commend the gcode event and uncomment the steppers initalize it also works so from what i understand it has something to do with the memory.

i am not even drawing anything to the OLED screen. if i comment that part it also works so my question is how can i optimize the gcode event and not using strings instead use only bytes
 
Upvote 0

thetahsk

Active Member
Licensed User
Longtime User
Use the correct function for the StackBuffer Size
B4X:
Log("StackBufferUsage: ", StackBufferUsage)
 
Upvote 0

ilan

Expert
Licensed User
Longtime User
Use the correct function for the StackBuffer Size
B4X:
Log("StackBufferUsage: ", StackBufferUsage)

ok , where should i put it? at the end of Appstart event?
 
Upvote 0

ilan

Expert
Licensed User
Longtime User
removing the OLED library everything works fine because it frees about 800 bytes that is almost 40% of what it was using before now i have left 1137 bytes and it is enough.
i really would like to show the process on the OLED but i guess the lib is taking to much memory. maybe i will switch to arduino mega
 
Upvote 0

thetahsk

Active Member
Licensed User
Longtime User
ok , where should i put it? at the end of Appstart event?
You can determin the stackbuffersize e.g. in your testGcode function.
B4X:
Sub testGcode(b() As Byte)
    'Z-Axis (Wire pusher) Pos1
    'C-Axis (Gear control) Pos2
    'A-Axis (Bender Control) Pos3
    
    gcodeLast = 0
    Dim AxisStep(3) As String
    Dim bc As ByteConverter
    Log("StackBufferUsage t0:",TAB,StackBufferUsage)
    For Each s0() As Byte In bc.Split(b, ",")
        If bc.IndexOf(s0,"/") > -1 Then
            Dim count As Int = 0
            For Each s1() As Byte In bc.Split(s0,"/")
                AxisStep(count) = bc.StringFromBytes(s1)
                count = count + 1
            Next
            'Dim line() As Byte = "test"' JoinStrings(Array As String( "Z",AxisStep(0), " C",AxisStep(1)," A",AxisStep(2)))
            gcodeArr(gcodeLast) = JoinStrings(Array As String( "Z",AxisStep(0), " C",AxisStep(1)," A",AxisStep(2)))
            '            If lines(1).Length = 0 Then
            '                lines(1) = line
            '            else if lines(2).Length = 0 Then
            '                lines(2) = line
            '            Else if lines(3).Length = 0 Then
            '                lines(3) = line
            '            Else
            '                lines(0) = lines(1)
            '                lines(1) = lines(2)
            '                lines(2) = lines(3)
            '                lines(3) = line
            '            End If
            'drawscreen(lines(0),lines(1),lines(2),lines(3))
        Else
            gcodeArr(gcodeLast) = bc.StringFromBytes(s0)
            '            If bc.IndexOf(s0,"P") > -1 Then
            'lines(0) = bc.StringFromBytes(s0)
            'drawscreen(lines(0),lines(1),lines(2),lines(3))
            '            Else
            '                If lines(1).Length = 0 Then
            '                    lines(1) = bc.StringFromBytes(s0)
            '                else if lines(2).Length = 0 Then
            '                    lines(2) = bc.StringFromBytes(s0)
            '                Else if lines(3).Length = 0 Then
            '                    lines(3) = bc.StringFromBytes(s0)
            '                Else
            '                    lines(0) = lines(1)
            '                    lines(1) = lines(2)
            '                    lines(2) = lines(3)
            '                    lines(3) = bc.StringFromBytes(s0)
            '                End If
            '                drawscreen(lines(0),lines(1),lines(2),lines(3))
            '            End If
        End If
        gcodeLast = gcodeLast + 1
    Next
    
    Log("gcode length: ", gcodeLast)
    Log("finished")
    Log("StackBufferUsage t1:",TAB, StackBufferUsage)
End Sub
 
Upvote 0
Top