Hydra freeze after some time

Hi,
I don’t know why, but my hydra board freeze after executing a simple Software I2C code with a timer. I run the code with the debugger but I see no error message at all. The code just stop executing. Do somebody has similar issue? Is it a timer problem? How could I track where and when the code stop if the debugger show me nothing?

Thank you.

Have you tried to pause the debugger and see what is happening on the system?

My first assumption, when I have a program problem, is that I have done something wrong, and
it is not a problem with MF or a library. I then work on isolating the problem.

You can add Debug.Print messages to trace what is happening in the system, to aid in
determining what happened to disrupt normal program execution.

Build a simple program, which displays your problem, and post in. Maybe someone
would see a problem.

Are you using 4.1 or 4.2? We’ve discovered other problems with 4.2 regarding SoftwareI2C. Maybe there’s a relation.

We needed a protocol analyzer to figure out that softwareI2C has some trouble… try to show code too see if other eyes can figure the problem …

Your slave device could be doing “clock stretching” but then it is “stretching” it too much!

@ ianlee74
I’m using 4.2 with visual basic.

@ Mike
Probably my code has something wrong, but despite my debug.print I can’t isolate the problem. The fact is that I have only a timer who is executing code and after a great number of execution, everything stop working, and the device does not respond anymore to Visual Basic debugger. Maybe, I could try to determine how much iteration are done before freeze.

@ dobova
I will paste my code tomorrow at home.

Still have the issue with the latest SDK (24 may 2012). I will try using “GT.Timer” instead of “System.Threading.Timer”. Maybe it will help! Otherwise, I will investigate the I2C Stretching phenomena.

Here is my code :

Imports System
Imports Microsoft.SPOT
Imports System.Threading
Imports Gadgeteer.Interfaces

Public Class HyperionHydraCore

    'Définition des propriétés d'exécution 
    Property I2C_Execute As Boolean = True

    'Instanciation d'un module Hyperion_OR8_A
    Dim myOR8_A As New Hyperion_OR8_A

    ' Software I2C Variables
    Dim ValueToWrite As Long = 255
    Dim bitShift As Integer = 0
    Dim ByteToWrite As Byte() = New Byte(0) {}
    Dim myI2C As SoftwareI2C
    Dim I2C_CLOCK_IN_kHz As Integer = 100
    Dim myI2CSocket As Gadgeteer.Socket = Gadgeteer.Socket.GetSocket(7, True, Nothing, Nothing)

    Public Sub ProgramStarted()

        ' Use Debug.Print to show messages in Visual Studio's "Output" window during debugging.
        Debug.Print("Program Started")

        myI2C = New SoftwareI2C(myI2CSocket, Gadgeteer.Socket.Pin.Three, Gadgeteer.Socket.Pin.Four, Nothing)

        Try
            Dim dataOut As Byte = 0
            Dim EEPROM_BYTE_ARRAY As Byte() = New Byte(5) {}
            EEPROM_BYTE_ARRAY(0) = CByte(&H0) 'Sert à signaler une écriture en lot
            EEPROM_BYTE_ARRAY(1) = CByte(&H2)
            EEPROM_BYTE_ARRAY(2) = CByte(&H4)
            EEPROM_BYTE_ARRAY(3) = CByte(&H8)
            EEPROM_BYTE_ARRAY(4) = CByte(&H10)
            EEPROM_BYTE_ARRAY(5) = CByte(&H20)
            ' Fill the EEPROM page beginning at memory location 0 ...
            myI2C.Write(myOR8_A.MICROCHIP_24C02C_ADDRESS, EEPROM_BYTE_ARRAY, SoftwareI2C.LengthErrorBehavior.ThrowException)

            dataOut = myI2C.ReadRegister(myOR8_A.MICROCHIP_24C02C_ADDRESS, CByte(&H0))
            Debug.Print("Value read from eeprom location 0 : " & dataOut.ToString())
            dataOut = myI2C.ReadRegister(myOR8_A.MICROCHIP_24C02C_ADDRESS, CByte(&H1))
            Debug.Print("Value read from eeprom location 1 : " & dataOut.ToString())
            dataOut = myI2C.ReadRegister(myOR8_A.MICROCHIP_24C02C_ADDRESS, CByte(&H2))
            Debug.Print("Value read from eeprom location 2 : " & dataOut.ToString())
            dataOut = myI2C.ReadRegister(myOR8_A.MICROCHIP_24C02C_ADDRESS, CByte(&H3))
            Debug.Print("Value read from eeprom location 3 : " & dataOut.ToString())
            dataOut = myI2C.ReadRegister(myOR8_A.MICROCHIP_24C02C_ADDRESS, CByte(&H4))
            Debug.Print("Value read from eeprom location 4 : " & dataOut.ToString())

        Catch ex As Exception
            Debug.Print("Exception - " + ex.Message)
        End Try

        'Initialisation des relais à l'état éteint
        Try
            ByteToWrite(0) = CByte(ValueToWrite)
            myI2C.Write(myOR8_A.NXP_PFC8574A_ADDRESS, ByteToWrite, SoftwareI2C.LengthErrorBehavior.ThrowException)
        Catch ex As Exception

        End Try
        ' Définitions des timers
        Dim timer As New System.Threading.Timer(New TimerCallback(AddressOf TimerOR8_Tick), Nothing, 0, 1000)

    End Sub

    Private Sub TimerOR8_Tick(state As Object)
        Try
            If I2C_Execute Then
                ValueToWrite = 255
                Clear(ValueToWrite, bitShift)
                ByteToWrite(0) = CByte(ValueToWrite)
                myI2C.Write(myOR8_A.NXP_PFC8574A_ADDRESS, ByteToWrite, SoftwareI2C.LengthErrorBehavior.ThrowException)
                Thread.Sleep(5)

                If bitShift < 7 Then
                    bitShift += 1
                Else
                    bitShift = 0
                End If
            End If
        Catch ex As Exception
            Debug.Print("Exception - " + ex.Message)
        End Try

    End Sub

    Private Sub Clear(ByRef ba As Long, bit As Integer)
        Dim mask As Long = 1L << bit
        mask = Not mask
        ba = ba And mask
    End Sub

End Class

These are not errors! Please start new thread whit your unrelated questions.

I just did a test with GT.timer instead of System.Threading.Timer and it’s working. I’m not sure to understand why right now, but I know I will use GT.timers for my project

Old code

Dim timer As New System.Threading.Timer(New TimerCallback(AddressOf TimerOR8_Tick), Nothing, 0, 1000)

New Code


Dim TimerOR8 As New GT.Timer(1000)
AddHandler TimerOR8.Tick, AddressOf TimerOR8_Tick
TimerOR8.Start()

@ jango_jas, I suspect and might be completely wrong, but the .NETMF timer fires the event on the timer thread, but the Gadgeteer timer has it’s event marshalled to the Dispatcher thread, this will remove the risk of race conditions with the UI components. I have not looked though your earlier posts, but this might be something to look into.

I think it is