Society of Robots - Robot Forum

Software => Software => Topic started by: dragonlord on October 03, 2012, 03:40:28 PM

Title: This might be a solution looking for a problem
Post by: dragonlord on October 03, 2012, 03:40:28 PM
As I've never programmed robots (have thought about getting involved in it at some point).  But it occured to me that I've never heard of a modular way that to easily extend the control unit to many components.  So as I was thinking about it I came up with this idea.  I'm sure that someone will tell me if it already exists.

How about if you had a module/hub that you could plug components that used the same interface into, at which point the ID of the component will be made up of the port it's plugged into plus the port that the hub is plugged into (+ as many hubs as have been chained together).  The plugged in points can then communicate back to the CPU/out host or be communicated with.

I think the code may explain my idea better. (VB.net)

Code: [Select]
Imports System.ComponentModel
Imports System.Threading

Public Enum NerveMessage As UInteger
    ReturnId
    NerveId
    ReturnStatus
    CurrentStatus
    AddNerve
    RemoveNerve

End Enum

Public Class Nerve

    Private _InputStream As IO.MemoryStream
    Private _ReturnStream As IO.MemoryStream

    Private _ReturnThread As BackgroundWorker
    Private _InputThread As BackgroundWorker

    Public CanSendSemaphore As New Semaphore(0, 1)
    Public CanReturnSemaphore As New Semaphore(0, 1)
    Dim _ID As Byte

    Public ReadOnly Property ID As Byte
        Get
            Return _ID
        End Get
    End Property

    Public Event Contract(nerve As Nerve, intensity As Integer)

    Public Event Relax(nerve As Nerve, intensity As Integer)

    Private Property Nodes As List(Of Nerve)

    Private Property ParentNerve As Nerve

    Public ReadOnly Property InputStream As IO.Stream
        Get
            If _InputStream Is Nothing Then
                _InputStream = New IO.MemoryStream
                _InputStream.ReadTimeout = 1000000
            End If

            Return _InputStream
        End Get
    End Property

    Public ReadOnly Property ReturnStream As IO.Stream
        Get
            If _ReturnStream Is Nothing Then _ReturnStream = New IO.MemoryStream
            Return _ReturnStream
        End Get
    End Property

    Public Sub ReadStream(stream As IO.MemoryStream)
        While True
            Dim b As Integer = stream.ReadByte
            If b > -1 Then
                If b = 254 Then
                    ParentNerve.CanReturnSemaphore.WaitOne()
                    Do
                        ParentNerve.ReturnStream.WriteByte(b)
                        b = InputStream.ReadByte
                    Loop Until b = 255
                    ParentNerve.ReturnStream.WriteByte(b)
                    For x As Integer = 1 To 6
                        b = stream.ReadByte
                        ParentNerve.ReturnStream.WriteByte(b)
                    Next
                    ParentNerve.CanReturnSemaphore.Release()
                ElseIf b = 255 Then
                    Dim instruction As String = "&H"
                    For x As Integer = 0 To 3
                        instruction += Hex(stream.ReadByte)
                    Next
                    Dim value As String = "&H"
                    For x As Integer = 0 To 3
                        value += Hex(stream.ReadByte)
                    Next
                    PerformMessage(CInt(instruction), CInt(value))
                Else
                    Dim nerve As Nerve = Nodes(b)
                    nerve.CanSendSemaphore.WaitOne()
                    Do
                        b = stream.ReadByte
                        nerve.InputStream.WriteByte(b)
                    Loop Until b = 255
                    nerve.InputStream.WriteByte(b)
                    For x As Integer = 1 To 8
                        b = stream.ReadByte
                        nerve.InputStream.WriteByte(b)
                    Next
                    nerve.CanSendSemaphore.Release()
                End If
            End If

        End While
    End Sub


    Public Sub SendMessage(Instruction As Integer, value As Integer)
        Dim ConvArr() As Byte = BitConverter.GetBytes(Instruction)
        ParentNerve.CanReturnSemaphore.WaitOne()
        ParentNerve.ReturnStream.WriteByte(254)
        ParentNerve.ReturnStream.WriteByte(ID)
        ParentNerve.ReturnStream.WriteByte(255)
        For Each Val As Byte In ConvArr
            ParentNerve.ReturnStream.WriteByte(Val)
        Next
        ConvArr = BitConverter.GetBytes(value)
        For Each Val As Byte In ConvArr
            ParentNerve.ReturnStream.WriteByte(Val)
        Next
        ParentNerve.CanReturnSemaphore.Release()
    End Sub

    Protected Overridable Sub PerformMessage(instruction As Integer, value As Integer)
        Select Case CType(instruction, NerveMessage)
            Case NerveMessage.AddNerve
                Nodes.Add(New Nerve(Me, Nodes.Count))
            Case NerveMessage.RemoveNerve
                Nodes.RemoveAt(value)
            Case NerveMessage.ReturnStatus
                SendMessage(NerveMessage.CurrentStatus, 1)
            Case NerveMessage.ReturnId
                SendMessage(NerveMessage.NerveId, ID)
        End Select
    End Sub

    Public Sub New(Nerve As Nerve, id As Byte)
        ParentNerve = Nerve
        _ID = id
    End Sub
End Class

Title: Re: This might be a solution looking for a problem
Post by: mstacho on October 04, 2012, 09:25:13 AM
Hm, that sounds a lot like USB, or SPI, or...honestly just about every type of computer connection that's out there :-P  If you really want to drive yourself nuts, try learning to get I2C working between multiple devices!

MIKE
Title: Re: This might be a solution looking for a problem
Post by: dragonlord on October 04, 2012, 02:52:13 PM
Ok, I've never looked at that sort of thing before.  But I'm glad in a way that my mind is working in the same way as the inventors of these protocols.