PDA

View Full Version : Background polling of a sensor



4Alex
01-06-2009, 09:35 PM
Hi all,

I am looking for some pointers in how to achieve background polling of a sensor at regular, periodic intervals of time. I want to start small but eventually I'd like to evolve this project into full home automation (and preferably not burn down my house in the process!).

Basically, I have a PC linked to a propeller using RS232 through pcFullDuplexSerial4FC.spin written by Ken Gracey and modified by Tim Moore. On the propeller side, I have a sensor linked through spi (spi.spin) that can be accessed at high bitrate. The propeller runs autonomously and monitors changes in the sensor data. When data is outside a preset range, an alarm is sent to the PC. If the range needs to be adjusted, the PC sends a command to do so. Simple. This is all working at this point but in full 'foreground' approach like with a traditional microcontroller.

I am looking at a way to have the propeller polling the sensor in the background while it still do other internal processing and responding to commands coming from the PC (or sending alarm to it). I guess the multi-cog design is what the propeller is really all about but I have no idea on how to achieve this.

The best would be if someone can point me toward an existing project doing something similar (background polling) so I can learn the ropes. I have searched the obex but with no success.

As always, many thanks in advance for any assistance.

Cheers,

Alex

Mike Green
01-06-2009, 10:08 PM
Start with the Propeller Education Kit tutorials, particularly the one on Methods and Cogs. There are other tutorials as well, all linked from the "sticky threads" at the top of the forum thread list.

The Propeller really doesn't have a "background". It has 8 essentially identical computers (cogs) that have access to the same I/O and memory. It's simply a matter of one computer polling the SPI sensor and leaving information in the shared memory while another computer is talking to a PC and looking at the shared memory information to see if there's something to send to the PC (while another computer is actually doing the serial I/O, bit by bit based on data in a shared buffer).

Kye
01-06-2009, 10:17 PM
As mike said, you should use the power of the·8·cog each to monitor data and respond to events.

Mostlikely, you should have one cog doing serial. One cog doing spi, and one interpreting the data from the PC and interpreting data from the sensor. All that's left to do is then add more cogs for more sensors to interface with them.

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Nyamekye,

Ken Gracey
01-06-2009, 10:18 PM
Somebody said...
. . . . ·using RS232 through pcFullDuplexSerial4FC.spin written by Ken Gracey and modified by Tim Moore.
Thanks for the compliment, but that would be "Chip" Gracey. We share a last name but we're wired differently.

Ken Gracey
Parallax, Inc.

·

4Alex
01-06-2009, 10:22 PM
@Ken & Chip:

I stand corrected! My sincere apologies to Chip. You might be 'wired differently' but you certainly both rock!

Cheers,

Alex

GeorgeCollins
01-08-2009, 11:52 AM
4Alex,

This is something that a prop is great for. I have been working on a robot where I have on thread (or cog) update the position of servos incrementally and another thread poll a Ping sensor. Both updates can go on in the background and the main processing loop doesn't have to wait for them.

When I start the ping I set the timing interval. The ping is read at that interval and the result goes into a ring buffer along with the servo position. So I can take a bunch of readings and then average them for more reliability. Or I can pan the head servo and see if any of the readings are dangerously close. Finally I sometimes use array of ping results and servo position to make a little obstacle plot on a TV screen. I am just learning, its amazing what I think I can do.

Enclosed is "Ping Minder" the part that monitors a Parallax ping sensor. It uses This isn't the greatest code, but perhaps it will help you. Let me know if I can help.





{{
Ping Minder

Do a ping every.. "PingDelay".. tics
Store result in a buffer.

}}

OBJ
Ping : "Ping" ' From the Parallax Object Exchange

CON

MAX_BUFFER = 100 ' How many readings I save
PING_ON = 1
PING_OFF = 0

VAR
byte PingPin
long PingDelay
long cm
long stack[512]
long measure_ring_buffer[MAX_BUFFER+1]
long servo_ring_buffer[MAX_BUFFER+1]
long servo_ptr
byte PingOn ' 1 ping is on, 0 ping is off
byte index
byte cog


PUB Init(pin, delay)
PingPin:=pin
PingDelay:=delay
servo_ptr:=0 ' So I know I haven't set it
PingOn:=1
cog:=cognew(Main, @Stack)
return cog

PUB SetServoPtr(ptr)
servo_ptr:=ptr

PUB GetServoPtr
return servo_ptr

PUB StartSweep
' Mark a sweep from one move to another

repeat index from 0 to MAX_BUFFER-1
if (servo_ptr > 0 )
servo_ring_buffer[index]:=long[servo_ptr]

index:=0

PUB GetIndex
return index

PRI Main
repeat
waitcnt(cnt+PingDelay)
if (PingOn==PING_ON)
cm:=Ping.Centimeters(PingPin)
index:=index+1
if (index > MAX_BUFFER-1)
index:=0
measure_ring_buffer[index]:=cm
if (servo_ptr > 0 )
servo_ring_buffer[index]:=long[servo_ptr]

PUB GetPingDistance
return cm


PUB GetPingAtLast(n)
' Get one of the recent pings, counting back n. n = 0 is the last ping
if (index - n > 0)
return measure_ring_buffer[index - n]
else
return measure_ring_buffer[index + MAX_BUFFER - n]

PUB GetPingAt(n)
if (n > -1) and (n < MAX_BUFFER)
return measure_ring_buffer[n]

PUB GetPanServoAt(n)
if (n > -1) and (n < MAX_BUFFER)
return servo_ring_buffer[n]

PUB GetAverageDistance(num_measure) | loop, bindex,sum
if (num_measure > MAX_BUFFER) or (num_measure < 1)
return 0 ' You can't average more then you buffer or 0

sum:=0
bindex:=index ' backward index
repeat loop from 0 to num_measure-1
sum:=sum+measure_ring_buffer[bindex]
bindex:=bindex- 1 ' go backward
if (bindex < 0)
bindex:=MAX_BUFFER ' wrap it around

if (num_measure > 1)
return sum/(num_measure)
else
return sum
PUB SetPingOn
PingOn:=PING_ON

PUB SetPingOff
PingOn:=PING_OFF

PUB Stop
cogstop(cog)

4Alex
01-08-2009, 09:11 PM
@GeorgeCollins:

Thank you so much for the code! It looks like a very good start for what I am trying to do. I will study your code and adapt it to my sensor. More to come later on...

Many thanks again.

Cheers,

Alex