In another thread I posted a quite detailed explanation of how to get the uDrive talking to both vb.net and to assembly language. However, a similar process with the uCam is proving much more difficult.
Ok, tools of the trade include software that can talk to the serial port (vb.net and robot basic) and two serial ports so you can loop data back and emulate things. Also, a serial port sniffer is essential which I got for free but I see they are charging a small royalty now http://www.serial-port-monitor.com/index.html Ultimately this is going to be ported to the Propeller but for the moment the task is getting it working talking to a PC
I have the software supplied with the device which is very useful for following the commands.
The problem is that to create this software takes hours (days even) building it up one line at a time and checking it works. I've got as far as command AA04 but it is proving very hard to debug.
Problems: The device shuts down if you only get half way through doing something. So lots of power cycles are required. The reset command AA08 does not seem to work. And even the supplied software hangs quite often, so clearly this doesn't have a reliable reset mechanism. Bootups are inconsistent - you can send it a series of commands and get ACKs back, and they cycle the power, give the same commands and it won't work. The number of initialisation commands can be up to 60 but sometimes it works with only one, and it is unclear when to stop sending these, and the number can vary so doing one for one comparisons with the supplied program is difficult. And doing comparisons is difficult too - eg in section 5.4.1 is a supplied series of instructions for a 640x480 jpeg but the trace is not the same on the supplied program - eg there is no command for a snapshot AA05, and the command for the size is AA01 00 07 07 07 but on the trace it is AA01 00 07 03 07. The package size doesn't match either.
Having spent a whole day on this (and having cracked the code for the uDrive), I'm wondering if there is some more information available:
* A reliable reset mechanism that works regardless of the module being only half way through a previous initialisation
* A consistent number of initialisation packets - even if this means adding in time delays between various steps
* And if at all possible, some source code so it is possible to single step through the commands and trace things more slowly?
Also, maybe my module was a one-off, but it came supplied with a D9 connector (at no extra cost, thanks++), but the power and data lines were transposed inside the D9 shell (lucky RS232 is robust!)
Any help with some source code would be most appreciated!
Addit: This is only partially complete, but it is returning the first 512 bytes of the picture now. Reboots are still unreliable, and there is an extra Ack needed that isn't in the manual. But we are making progress!
Dim WithEvents SerialPort As New IO.Ports.SerialPort ' serial port declare
Public Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Integer) ' for sleep statements
Public InPacket(0 To 2000) As Byte ' bug with serial.write strings like chr(255) won't go out
Public OutPacket(0 To 50) As Byte ' usually only send out a few bytes though so could make this smaller
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim i As Integer
SerialPort.PortName = TextBox1.Text
SerialPort.BaudRate = TextBox2.Text
SerialPort.Parity = IO.Ports.Parity.None ' no parity
SerialPort.DataBits = 8 ' 8 bits
SerialPort.StopBits = IO.Ports.StopBits.One ' one stop bit
SerialPort.ReadTimeout = 1000 ' milliseconds so times out in 1 second if no response
Try
SerialPort.Open() ' open the port
SerialPort.DiscardInBuffer() ' clear the input buffer
'Reset()
'Sleep(1000)
'GetPacket()
TextBox3.Text += "Waking up camera" + vbCrLf
Application.DoEvents()
i = 0
Do
Synch()
Sleep(10) ' wait for response
Application.DoEvents() ' update the display
i += 1
TextBox3.Text += "."
Loop Until i > 60 Or SerialPort.BytesToRead >= 6
If i > 60 Then TextBox3.Text += "No response after 60 tries" + vbCrLf
TextBox3.Text += vbCrLf + "Waiting 3 secs to adjust brightness and colour" + vbCrLf
GetPacket()
Sleep(1000) ' delay
SerialPort.DiscardInBuffer() ' clear the input buffer
SendAck()
Sleep(2000) ' to adjust brightness etc
jpeg() ' send instructions for a jpeg
GetSixBytes()
PackageSize()
GetSixBytes()
'Snapshot()
'GetSixBytes()
GetPicture()
GetSixBytes()
SendAck() ' yes this is needed but it isn't in the manual
' now get 512 bytes
Get512Bytes()
SerialPort.Close()
Catch ex As Exception
SerialPort.Close()
TextBox3.Text += "Timeout error" + vbCrLf
End Try
End Sub
Private Sub GetPacket()
' read 6 bytes back from the uCam
Dim i As Integer
Dim h As String
SerialPort.Read(InPacket, 0, 6) ' read 6 bytes back
For i = 0 To 5
h = Hex(InPacket(i))
If Val("&H" + h) < 16 Then h = "0" + h ' add leading zero
TextBox3.Text += h + " "
Next
If InPacket(1) = 15 Then ' NAK error
TextBox3.Text += " Error number (p10 manual) = " + Str(InPacket(4))
End If
If InPacket(1) = 14 Then ' ACK - print number
TextBox3.Text += "Ack command " + Str(InPacket(2)) + " number " + Str(InPacket(3))
End If
TextBox3.Text += vbCrLf
Application.DoEvents() ' refresh the display
End Sub
Sub GetSixBytes()
Do
Loop Until SerialPort.BytesToRead >= 6
GetPacket()
End Sub
Private Sub Get512Bytes()
TextBox3.Text += "Waiting for bytes to come in..." + vbCrLf
Application.DoEvents()
Sleep(2000)
TextBox3.Text += "Number of bytes to read " + Str(SerialPort.BytesToRead) + vbCrLf
'SerialPort.Read(InPacket, 0, 512) ' read 512 bytes back
' but is it 512+ the header bytes?
Application.DoEvents()
End Sub
Private Sub SendAck()
OutPacket(0) = &HAA
OutPacket(1) = &HE
OutPacket(2) = &HD
OutPacket(3) = &H0
OutPacket(4) = &H0
OutPacket(5) = &H0
SerialPort.Write(OutPacket, 0, 6)
End Sub
Private Sub jpeg()
' jpeg 640
OutPacket(0) = &HAA
OutPacket(1) = &H1
OutPacket(2) = &H0
OutPacket(3) = &H7
OutPacket(4) = &H3
OutPacket(5) = &H1 ' tiny jpeg for testing first
SerialPort.Write(OutPacket, 0, 6)
End Sub
Private Sub PackageSize()
' 512 bytes
OutPacket(0) = &HAA
OutPacket(1) = &H6
OutPacket(2) = &H8
OutPacket(3) = &H0
OutPacket(4) = &H2 ' 2*256
OutPacket(5) = &H0
SerialPort.Write(OutPacket, 0, 6)
End Sub
Private Sub Snapshot()
' take the picture
OutPacket(0) = &HAA
OutPacket(1) = &H5
OutPacket(2) = &H0
OutPacket(3) = &H0
OutPacket(4) = &H0
OutPacket(5) = &H0
SerialPort.Write(OutPacket, 0, 6)
End Sub
Private Sub GetPicture()
' gets an ack then gets the bytes
OutPacket(0) = &HAA
OutPacket(1) = &H4
OutPacket(2) = &H5
OutPacket(3) = &H0
OutPacket(4) = &H0
OutPacket(5) = &H0
SerialPort.Write(OutPacket, 0, 6)
End Sub
Private Sub Reset()
' issue a reset command
OutPacket(0) = &HAA
OutPacket(1) = &H8
OutPacket(2) = &H0
OutPacket(3) = &H0
OutPacket(4) = &H0
OutPacket(5) = &H0
SerialPort.Write(OutPacket, 0, 6)
End Sub
Private Sub Synch()
OutPacket(0) = &HAA
OutPacket(1) = &HD
OutPacket(2) = &H0
OutPacket(3) = &H0
OutPacket(4) = &H0
OutPacket(5) = &H0
SerialPort.Write(OutPacket, 0, 6)
End Sub
End Class
Ok, tools of the trade include software that can talk to the serial port (vb.net and robot basic) and two serial ports so you can loop data back and emulate things. Also, a serial port sniffer is essential which I got for free but I see they are charging a small royalty now http://www.serial-port-monitor.com/index.html Ultimately this is going to be ported to the Propeller but for the moment the task is getting it working talking to a PC
I have the software supplied with the device which is very useful for following the commands.
The problem is that to create this software takes hours (days even) building it up one line at a time and checking it works. I've got as far as command AA04 but it is proving very hard to debug.
Problems: The device shuts down if you only get half way through doing something. So lots of power cycles are required. The reset command AA08 does not seem to work. And even the supplied software hangs quite often, so clearly this doesn't have a reliable reset mechanism. Bootups are inconsistent - you can send it a series of commands and get ACKs back, and they cycle the power, give the same commands and it won't work. The number of initialisation commands can be up to 60 but sometimes it works with only one, and it is unclear when to stop sending these, and the number can vary so doing one for one comparisons with the supplied program is difficult. And doing comparisons is difficult too - eg in section 5.4.1 is a supplied series of instructions for a 640x480 jpeg but the trace is not the same on the supplied program - eg there is no command for a snapshot AA05, and the command for the size is AA01 00 07 07 07 but on the trace it is AA01 00 07 03 07. The package size doesn't match either.
Having spent a whole day on this (and having cracked the code for the uDrive), I'm wondering if there is some more information available:
* A reliable reset mechanism that works regardless of the module being only half way through a previous initialisation
* A consistent number of initialisation packets - even if this means adding in time delays between various steps
* And if at all possible, some source code so it is possible to single step through the commands and trace things more slowly?
Also, maybe my module was a one-off, but it came supplied with a D9 connector (at no extra cost, thanks++), but the power and data lines were transposed inside the D9 shell (lucky RS232 is robust!)
Any help with some source code would be most appreciated!
Addit: This is only partially complete, but it is returning the first 512 bytes of the picture now. Reboots are still unreliable, and there is an extra Ack needed that isn't in the manual. But we are making progress!
Dim WithEvents SerialPort As New IO.Ports.SerialPort ' serial port declare
Public Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Integer) ' for sleep statements
Public InPacket(0 To 2000) As Byte ' bug with serial.write strings like chr(255) won't go out
Public OutPacket(0 To 50) As Byte ' usually only send out a few bytes though so could make this smaller
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim i As Integer
SerialPort.PortName = TextBox1.Text
SerialPort.BaudRate = TextBox2.Text
SerialPort.Parity = IO.Ports.Parity.None ' no parity
SerialPort.DataBits = 8 ' 8 bits
SerialPort.StopBits = IO.Ports.StopBits.One ' one stop bit
SerialPort.ReadTimeout = 1000 ' milliseconds so times out in 1 second if no response
Try
SerialPort.Open() ' open the port
SerialPort.DiscardInBuffer() ' clear the input buffer
'Reset()
'Sleep(1000)
'GetPacket()
TextBox3.Text += "Waking up camera" + vbCrLf
Application.DoEvents()
i = 0
Do
Synch()
Sleep(10) ' wait for response
Application.DoEvents() ' update the display
i += 1
TextBox3.Text += "."
Loop Until i > 60 Or SerialPort.BytesToRead >= 6
If i > 60 Then TextBox3.Text += "No response after 60 tries" + vbCrLf
TextBox3.Text += vbCrLf + "Waiting 3 secs to adjust brightness and colour" + vbCrLf
GetPacket()
Sleep(1000) ' delay
SerialPort.DiscardInBuffer() ' clear the input buffer
SendAck()
Sleep(2000) ' to adjust brightness etc
jpeg() ' send instructions for a jpeg
GetSixBytes()
PackageSize()
GetSixBytes()
'Snapshot()
'GetSixBytes()
GetPicture()
GetSixBytes()
SendAck() ' yes this is needed but it isn't in the manual
' now get 512 bytes
Get512Bytes()
SerialPort.Close()
Catch ex As Exception
SerialPort.Close()
TextBox3.Text += "Timeout error" + vbCrLf
End Try
End Sub
Private Sub GetPacket()
' read 6 bytes back from the uCam
Dim i As Integer
Dim h As String
SerialPort.Read(InPacket, 0, 6) ' read 6 bytes back
For i = 0 To 5
h = Hex(InPacket(i))
If Val("&H" + h) < 16 Then h = "0" + h ' add leading zero
TextBox3.Text += h + " "
Next
If InPacket(1) = 15 Then ' NAK error
TextBox3.Text += " Error number (p10 manual) = " + Str(InPacket(4))
End If
If InPacket(1) = 14 Then ' ACK - print number
TextBox3.Text += "Ack command " + Str(InPacket(2)) + " number " + Str(InPacket(3))
End If
TextBox3.Text += vbCrLf
Application.DoEvents() ' refresh the display
End Sub
Sub GetSixBytes()
Do
Loop Until SerialPort.BytesToRead >= 6
GetPacket()
End Sub
Private Sub Get512Bytes()
TextBox3.Text += "Waiting for bytes to come in..." + vbCrLf
Application.DoEvents()
Sleep(2000)
TextBox3.Text += "Number of bytes to read " + Str(SerialPort.BytesToRead) + vbCrLf
'SerialPort.Read(InPacket, 0, 512) ' read 512 bytes back
' but is it 512+ the header bytes?
Application.DoEvents()
End Sub
Private Sub SendAck()
OutPacket(0) = &HAA
OutPacket(1) = &HE
OutPacket(2) = &HD
OutPacket(3) = &H0
OutPacket(4) = &H0
OutPacket(5) = &H0
SerialPort.Write(OutPacket, 0, 6)
End Sub
Private Sub jpeg()
' jpeg 640
OutPacket(0) = &HAA
OutPacket(1) = &H1
OutPacket(2) = &H0
OutPacket(3) = &H7
OutPacket(4) = &H3
OutPacket(5) = &H1 ' tiny jpeg for testing first
SerialPort.Write(OutPacket, 0, 6)
End Sub
Private Sub PackageSize()
' 512 bytes
OutPacket(0) = &HAA
OutPacket(1) = &H6
OutPacket(2) = &H8
OutPacket(3) = &H0
OutPacket(4) = &H2 ' 2*256
OutPacket(5) = &H0
SerialPort.Write(OutPacket, 0, 6)
End Sub
Private Sub Snapshot()
' take the picture
OutPacket(0) = &HAA
OutPacket(1) = &H5
OutPacket(2) = &H0
OutPacket(3) = &H0
OutPacket(4) = &H0
OutPacket(5) = &H0
SerialPort.Write(OutPacket, 0, 6)
End Sub
Private Sub GetPicture()
' gets an ack then gets the bytes
OutPacket(0) = &HAA
OutPacket(1) = &H4
OutPacket(2) = &H5
OutPacket(3) = &H0
OutPacket(4) = &H0
OutPacket(5) = &H0
SerialPort.Write(OutPacket, 0, 6)
End Sub
Private Sub Reset()
' issue a reset command
OutPacket(0) = &HAA
OutPacket(1) = &H8
OutPacket(2) = &H0
OutPacket(3) = &H0
OutPacket(4) = &H0
OutPacket(5) = &H0
SerialPort.Write(OutPacket, 0, 6)
End Sub
Private Sub Synch()
OutPacket(0) = &HAA
OutPacket(1) = &HD
OutPacket(2) = &H0
OutPacket(3) = &H0
OutPacket(4) = &H0
OutPacket(5) = &H0
SerialPort.Write(OutPacket, 0, 6)
End Sub
End Class
Comment