Thursday, August 24, 2006
I had noticed that when I sent a query to the PIC controlling the GM4 motor that sometimes I didn't get anything back. It was easy enough to do workarounds for that situation and I didn't really think too much about it. I figured that it was just some sort of mismatch.
I was right and wrong. Apparently, when I sent out a query code to the board after I'd put to going somewhere on the axis at a given speed the CPU occasionally got from the line of .NET code where the query went out to the line of code where the answer was expected back faster than the PIC could respond.
While it was an occasional problem while the GM4 was being directed to go clockwise it was a constant problem when I told it to go counterclockwise. I'm not sure why that was so, but it was.
I cured up the .NET problem by putting a half-second pause between the query and the return string (57 bytes). Having to convert Long integers to an equivalent ASCII string is a non-trivial task for the 16F628A. I'd like to just send over the integers as integers, but the PIC integers don't do 2's complement maths to talk about negative numbers like .NET does so I'll have to sit down and write a 2's complement routine to convert what I get from the PIC over the serial port into something .NET can understand.
Anyhow, I have the serial comms control programme talking reliably with the PIC GM4 board regardless of the direction it's been told to go now, so I should be able to automate the calibration of the PWM/pulse and overshoot tables. I'm going to try to move those tables over to the EEPROM memory in that they take quite a bit of RAM and programme memory right now.
If I've read the manual correctly while I can't do a bootload with the 16F628A I may be able to reprogramme the EEPROM memory over the serial link if I am careful. That would let me update the tables without having to reprogramme the whole PIC chip. That would be nice.
If it is the latter, you should be able to create a timer that polls the port.
In the Windows.Forms layout, add a Timer component, and set the resolution to ~250 milliseconds or so. Set timer.Enabled = true at an appropriate time (in the form's Load event, or after you initialize the serial port.)
The timer_Tick event handler would then check for data on the serial line, and put it in a form that you can consume.
Generally, event driven code or state based operation is preferable when doing this kind of thing.
This would allow you to have the pic send unqueried data to the PC -- as well as solving the problem when the PIC does not have time to respond. For example, you could, every second, send a signal indicating the position and speed of the motor, without any prompting from the host.
It appears to be trying to read before the PIC has had a chance to create the data string.
***If it is the latter, you should be able to create a timer that polls the port.***
I have a feeling that that option is already in the code that I stole from Corrado Cavalli at http://www.codeworks.it/net/VBNetRs232.htm
I just haven't had time to go through his routines line by line and find it. For right now putting in a tuned wait command does a good enough job.
In any case, if you're happy then that's all that matters. :) I was just suggesting a solution to solve the issue you saw, and also allow passive data indication (I.E, you don't need to send a query command to get the PIC to say something... it can just say it anytime it wants to..)
The bits you are looking for aren't in the Form1. They're in the cRs232 module. They're really nasty high level VB.NET code that Corrado wrote and that I have to read with my finger on the line. That's why I haven't done good fixes to the problems yet. :-)
Pop me an email address and I'll send you a copy. I'd put it on my server but it's buggered right now. :-(
Create a SerialPort object, set the parameters on it, attach an event handler to the DataReceived event, send information out via the write method...
If you're specifically stopping to wait for a response, you're not creating OO code, you're creating procedural code...
You should ALWAYS be waiting for data from the PIC, and either handling that data as you get it, or storing it somewhere to be used 'later'...
...are you using triggers and events in your code?
I could be missing the point, but it looks like some patch job to hook into the API, instead of using the built in SerialPort class in .NET... maybe SerialPort is new to 2005? I noticed that example was 2003 maybe?
Look at the System.IO.Ports.SerialPort class, it has the event handler/etc. I would guess that it does everything you need to do, and either it wasn't available back in '2003', or it just isn't 'used'/'known' in VB.NET...?
Are you familiar with using events to handle the receiving of data? it didn't sound like you were using them in your post, but the RS232 class appeared to have the same sort of event as the SerialPort.DataReceived event.
Thanks for the tip. Don't need the source now. Should be able to throw something together in a matter of minutes. SerialPort class seems to be just what is needed here, for .NET programming.
Not sure when the Z8 programmer and chips will arrive. Will have some fun when they do.
I can see that it would be. Unfortunately, I just checked and it appears that that feature was only implimented in .NET 2.0 which was released in 2005. I'll have to dig around and see if I can find those upgrade disks. :-(
Links to this post: