Shop OBEX P1 Docs P2 Docs Learn Events
Ping sensor in New Cog — Parallax Forums

Ping sensor in New Cog

BotdocterBotdocter Posts: 271
edited 2010-05-04 16:38 in Propeller 1
My bot uses scripts that make my ping sensor pause for the duration of those functions. So i want to run the ping in a new cog. It runs for about 15 secons then gets stuck. The robot is all over the place (going left right backwards and god know where else!) for the same 15 seconds and then the program gets stuck.
what did i do wrong?

This is what i tried:
[noparse][[/noparse]code]cognew(PingCog(@distance), @PingStack)[noparse][[/noparse]/code]

and then...

[noparse][[/noparse]code]PUB PingCog(distance)
'Get Ping))) reading at all times.
······· repeat····
········· distance := ping.Centimeters(PING_Pin)············································ 'Get Range In Millimeters
········ long[noparse][[/noparse]distance] *= long[noparse][[/noparse]range]································ ' Ping value, store back
········ waitcnt(clkfreq + cnt)[noparse][[/noparse]/code]

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
1 Parallax Propeller Robot Control Board
1 Memsic MX2125 accelerometer/ tilt
1 Parallax Ping))) ultrasonic sensor

a few motors and a whole lot of chaos!

Comments

  • kuronekokuroneko Posts: 3,623
    edited 2010-05-04 01:14
    PUB PingCog(distance) 
    'Get Ping))) reading at all times.
            repeat     
              distance := ping.Centimeters(PING_Pin)                                             'Get Range In Millimeters
    
             long[noparse][[/noparse]distance] *= long[noparse][[/noparse]range]                                 ' Ping value, store back
             waitcnt(clkfreq + cnt)
    


    Do you really intend to overwrite the address of your distance variable with the range? And where/how is range (another address) defined?
  • BotdocterBotdocter Posts: 271
    edited 2010-05-04 01:46
    I just changed the adress because the example code i used from the manual used two adresses and the code seemed to work like this. i just need the range value. it will be called for in IF commands for stopping and turning.

    example: IF range < 30
    Turnleft

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    1 Parallax Propeller Robot Control Board
    1 Memsic MX2125 accelerometer/ tilt
    1 Parallax Ping))) ultrasonic sensor

    a few motors and a whole lot of chaos!
  • kuronekokuroneko Posts: 3,623
    edited 2010-05-04 01:51
    My point is that long[noparse][[/noparse]distance] has access to the whole hub memory depending on the value of distance. So if ping.Centimeters(pin) returns 16 then you access memory which you don't want to modify.
  • BotdocterBotdocter Posts: 271
    edited 2010-05-04 01:56
    ok i understand what you're saying, but i don't know anything about it. so if i understand right, i have to change 'distance' to 'range'? or in other words, keep range, range?

    will that solve my problem or is this another problem i have?

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    1 Parallax Propeller Robot Control Board
    1 Memsic MX2125 accelerometer/ tilt
    1 Parallax Ping))) ultrasonic sensor

    a few motors and a whole lot of chaos!
  • kuronekokuroneko Posts: 3,623
    edited 2010-05-04 02:06
    Why don't you start with telling us what you're trying to do with the range value returned from the ping object? Is it simply to be stored somewhere? Your comment mentions millimeters but the method itself suggests centimeters. So - wild guess here - maybe you want to store 10*range into distance?
  • BotdocterBotdocter Posts: 271
    edited 2010-05-04 02:14
    That's allready been calculated and done. I have all the code working allready. the output of range is all i need·all i need to run in the cog is :


    repeat
    range := ping.Centimeters(PING_Pin) 'Get Range In Centimeters

    So what do i need to wrap around this code to make it run in a new cog and what value's do i need to use for calling the new cog in the main script?

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    1 Parallax Propeller Robot Control Board
    1 Memsic MX2125 accelerometer/ tilt
    1 Parallax Ping))) ultrasonic sensor

    a few motors and a whole lot of chaos!
  • kuronekokuroneko Posts: 3,623
    edited 2010-05-04 02:34
    If range is a global variable then that's all you really need. Your method wouldn't need any extra parameters either. Just start it in a new cog and maybe put a delay into the range update loop.

    Post Edited (kuroneko) : 5/4/2010 2:40:12 AM GMT
  • kuronekokuroneko Posts: 3,623
    edited 2010-05-04 02:43
    Untested:

    CON
      pin = 0
      
    VAR
      long  range
      long  stack[noparse][[/noparse]40]
    
    OBJ
      ping: "Ping"
      
    PUB main
    
      cognew(PingCog, @stack{0})
      waitpne(0, 0, 0)
      
    PRI PingCog
    
      repeat
        range := ping.Centimeters(pin)
        waitcnt(clkfreq + cnt)
    
    DAT
    
  • GeorgeCollinsGeorgeCollins Posts: 132
    edited 2010-05-04 02:53
    Here is the code I use in the robot Fluffy (pictured) to sample a Ping sensor on a regular basis and save them in a ring buffer. The ping sensor pivots, so I also store its direction-- the servo value on which the sensor is mounted. Every so often I make a little map of the objects I have detected (to display) and also to do a crude probabilistic approach to my measurements. If I detect a certain number of obstacles in a quadrant, I assume the way is blocked. Sensors are generally more accurate if you take multiple readings.

    I use a ring buffer so that if I ignore the measurements for a long time I just discard the old ones and I do not run out of memory.


    {{
      Ping Minder
    
      Do a ping every.. blank.. seconds
    }}
    
    OBJ
      Ping  : "Ping"
    
    CON
    
      MAX_BUFFER    = 100           ' How many readings I save
      PING_ON       = 1
      PING_OFF      = 0
      
    VAR
      byte PingPin
      long PingDelay
      long cm
      long stack[noparse][[/noparse]512]
      long measure_ring_buffer[noparse][[/noparse]MAX_BUFFER+1]
      long servo_ring_buffer[noparse][[/noparse]MAX_BUFFER+1]
      long servo_ptr   ' ptr to the servo position value in another piece of code
      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
      index:=-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[noparse][[/noparse]index]:=long[noparse][[/noparse]servo_ptr]         ' BUT 109 WORKS, NOT SERVO PTR
    
        index:=-1
    
    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[noparse][[/noparse]index]:=cm
          if (servo_ptr > 0 )
            servo_ring_buffer[noparse][[/noparse]index]:=long[noparse][[/noparse]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[noparse][[/noparse]index - n]
        else
          return measure_ring_buffer[noparse][[/noparse]index + MAX_BUFFER - n]  
    
    PUB GetPingAt(n)
      if (n > -1) and (n < MAX_BUFFER)
        return measure_ring_buffer[noparse][[/noparse]n]
        
    PUB GetPanServoAt(n)  
       if (n > -1) and (n < MAX_BUFFER)
        return servo_ring_buffer[noparse][[/noparse]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[noparse][[/noparse]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)
    
    

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    My Robots
  • BotdocterBotdocter Posts: 271
    edited 2010-05-04 03:03
    Thanx! A lot!

    That is great since that's just what i whas looking for.

    But still my question raises..

    Can you give me an example of how to run this in a sepparate cog?

    I use the ping sensor for more tasks then one. So i want it to ping constantly ( every second or 0.5 second) and then the sensor values will be available even when the main script would stop reading because of other functions.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    1 Parallax Propeller Robot Control Board
    1 Memsic MX2125 accelerometer/ tilt
    1 Parallax Ping))) ultrasonic sensor

    a few motors and a whole lot of chaos!
  • BotdocterBotdocter Posts: 271
    edited 2010-05-04 03:48
    Sorry, i allready found it. Thanx again!

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    1 Parallax Propeller Robot Control Board
    1 Memsic MX2125 accelerometer/ tilt
    1 Parallax Ping))) ultrasonic sensor

    a few motors and a whole lot of chaos!
  • BotdocterBotdocter Posts: 271
    edited 2010-05-04 16:38
    Can you tell me what the max. Stack-space is?
    And is that per cog or for all cogs together?

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    1 Parallax Propeller Robot Control Board
    1 Memsic MX2125 accelerometer/ tilt
    1 Parallax Ping))) ultrasonic sensor

    a few motors and a whole lot of chaos!
Sign In or Register to comment.