SDM-IO ultrasonic and PICAXE code headache

Can't seem to wrap my head around this new sensor. Here's the best description of this sensor's operation yet:

"A short ultrasonic pulse is transmitted at the time T1, reflected by an object. The senor receives this signal and converts it to an electric signal. The next pulse can be transmitted when the echo is faded away. This time period is called cycle period. The recommend cycle period should be no less than 10ms. If a 10μs width trigger pulse is sent to the signal pin, the Ultrasonic module will output some 40kHz ultrasonic signal and detect the echo back, each back pulse width is 150us so there is different to HC-SR04 module.The measured distance we can’t use the echo pulse  width  to calculate by the formula, but can be calculated by

Formula: distance = (T2 – T1 – 250Us) * (High speed of sound(340M/S)) / 2                        // 250us is circuit delay’s time.

The arduino demo you can reference to HC-SR04, but you should note that transmitted signal is LOW to HIGH  trigger and you should not use  pulseIn() function for the pulse width, however you need start a Timer for count T1 and T2."

 

I also have this from what seems to be the manufacturer:

Main technical parameters:


1: Voltage: DC3.8-5.5V
2: Static current: less than 8mA
3: Output TTL level

 
4: Sensor angle: not more than 15 degrees
5: Detection Range: 0cm-1500mm 6: High Accuracy: up to 3mm
 
Module works:
 
(1) The IO triggers ranging from 0 to the TRIG signal at least 10us;
(2) the module automatically sends eight 40khz square wave, automatically detects whether a signal retur(3) a signal back, through the ECHO output 10 signal, TRIG = 1 to the ECHO is the ultrasonic duration of time from launch to return. Test distance = (time * High speed of sound (340M / S)) / 2;
(4) When the TRIG from 0 -> 1, the main control panel starts a timer to control the 10ms timeout control measurements, the time when the timeout 10ms 150us ECHO 0 still no signal that there is no obstacle.

Module main features:

(1) ultra-miniature, only the equivalent of two transmitting and receiving the first of the area, has been unable to be small.
(2) blind spot (8mm, forming a triangle within the larger error).
(3) fast response, 10ms measurement period, not easy to lose high-speed targets.
(4) transmitting the first, receiving the first close, and the measured linear relationship between the basic objectives (8mm or large within the triangle, this is the transmitting and receiving first determined the physical shape).
(5) module has LED indication, easy to observe and test! 
 
Short distance
 
 
Long distance
 
 
 
So this is what I get out of the info:
  • Sensor is activated with a trigger pulse >=10uS at logic LOW.
  • The echo pin remains high until timeout (10ms) or the reflected sonar pulses are received.
  • If an echo is heard, the echo pin will be held low for 150uS.
  • If timeout occurs, the echo pin will be held down for 10mS.

This is the code I've been tinkering on for a PICAXE 20X2:

#no_data
#no_table

symbol trig = C.2    'Define output pin for Trigger pulse
symbol echo = B.1    'Define input pin for Echo pulse, also interrupt pin
symbol echo_pin = pinB.1    'for use in timeout sequence
symbol IntCheck = bit0
symbol range = w1    '16 bit word variable for range
symbol R1 = C.7    'motor vars
symbol R2 = C.6
symbol L1 = C.4
symbol L2 = C.3
symbol ServoPin = B.0    'B.2 for testing
symbol piezo = C.0
symbol T1 = w2    '4-5
symbol T2 = w3    '6-7
symbol T3 = w4    '8-9
symbol T4 = w5    '10-11

high trig    'set trigger pin high

sensor_start:
DEBUG
wait 1
hintsetup %00000010    ; enable INT1 only, falling edge trigger
setintflags %00000010,%00000010    'activate INT1
timer3 = 0    'reset timer var
tmr3setup %10010001    'activate background timer3, 1:2 prescalar = 1uS/increment
low trig    'low to activate sensor
pauseus 2    'equals 2 * 10uS
high trig
T1 = timer3    'start time for distance calculations

sensor_dist:
if IntCheck = 0 then goto sensor_dist    'IntCheck = 1 when interrupt runs, stops loop
IntCheck = 0    'resets var after interrupt
if range = 9999 then goto sensor_start    'interrupt sub returns range=9999 if timeout occurs
T3 = T2 - T1- 250     'time between sending and receiving sonar signal
T4 = T3 * 1000    'picaxe sucks at math
T4 = T4/135
range = T4/2    'approximate calc for inch/second

goto sensor_start

interrupt:
T2 = timer3    'time when reflection is received
pauseus 15    'length of non-timeout pulsewidth = 150uS
if echo_pin = 0 then    'if echo_pin is still low, timeout occurred, ie no object found
 range = 9999    'value for timeout condition
endif
IntCheck = 1    'stops sensor_distance goto loop
hint1flag =0    'reset INT1 flag
DEBUG
return

 

The major problem I'm facing is the interrupt never gets triggered by a falling edge and the program loops the "sensor_dist" subroutine. It only refreshes the debug terminal once so I know it never gets to the second debug in the interrupt sub.

Any input valued, thanks.

I threw together a flowchart

of what I believe you would need to make your sensor work.

 
If you can translate that to PICAXE basic, you should at least get a string of numbers that vary given varied object distance. I am sure I could translate it for you, if you feel it necessary. :slight_smile:

Very nice, flowcharts are

Very nice, flowcharts are always useful. I think the problem I’m having is the “If ECHO” step. Assuming I’ve got my interrupt set up correctly, the echo pin isn’t triggering it. I can do trigger it manually but that’s cheating :slight_smile: I’m going to try and write a program to log the echo pin state from the time the trigger is activated till the memory runs out on the chip. The echo pin idles at logic high but my equipment isn’t sensitive enough to detect uS or mS changes, if indeed it’s happening.

I’m not married to the use of interrupts but it was the best (only) way I could think of to semi-accurately get timing out of this sensor. Any other coding ideas would be gladly heard.

Re: interrupts

They are really the only way to go. The only change to my flowchart would be that instead of if ECHO, you would setup an interrupt on the ECHO pin and then set the Obstacle bit to 1 if the ECHO line was pulled low for approximately 150uS. The flowchart was really a barebones lets try to get good data from the sonar. You might even get away with restarting the timer3 inside the interrupt to time the 150uS, just be sure to store the timer3 count in another variable. I believe I could throw together some PICAXE code for you to try, if you want me to.

EDIT
   The timer needs to be started outside of the while loop rather than inside as I diagramed.

EDIT2
   I was just looking over things and you can’t really move whie you are trying to get a reading, so, there should be no need for an interrupt. Simply moving the timer/counter start outside of the while loop ‘should’ suffice. 

Hum, first, i’m not a

Hum,  first, i’m not a picaxe guy and i don’t even own one so maybe i’ll say something very stupid but:

 

You said you are using a PICAXE20x2 and i see in your code

symbol echo = B.1    'Define input pin for Echo pulse, also interrupt pin

Looking at http://www.picaxe.com/docs/picaxe_manual2.pdf page 216 (setInt) it say:

Due to internal port configuration on some of the chips there is a limitation on
which pins can be used. The default input port is portC.
14M/14M2 only inputs 0,1,2 may be used
20M only inputs 1-5 may be used
20M2/20X2 only portC may be used, and only C.1 to C.5 on portC
40X2 when using portA, only A.0 to A.3 may be used

 

Did you tried using the portC with interrupt ?)

 

Ah I’m using hardware interrupts

At first I though you hit it on the head but I realized you were talking about the standard polled interrupts. The hardware ints on the 20X2 use b.0 and b.1. But now you got me thinking I don’t even have the right one connected to the echo pin. I so desire to leave work sick so I can go check lol

hum, after reading a little

hum, after reading a little more about picaxe:

<update before posting> > there is a difference between:

setintflags and setint… you are right

setintflags causes a polled interrupt on a certain flags condition.

setint causes a polled interrupt on a certain input pin condition.

I think you want to use setint and not setintflags

</update>

 

 

You want an interrupt when echo goes low, i think it should be

SETINT %00000000,%00000010

And from page 83, you forgot to reactivate your interrupt after clearing the intflag SETINT in the isr:

SETINT %00000000,%00000010

When the interrupt occurs, the interrupt is permanently disabled. Therefore to
re-enable the interrupt (if desired) a SETINT command must be used within
the interrupt: sub-procedure itself. The interrupt will not be enabled until the
‘return’ command is executed.

I considered using polled

I considered using polled interrupts but using the hardware version is slightly faster. Probably not noticeable but it makes me feel better. My understanding is “setint” causes polled interrupts which are checked between the execution of each line of code. “setintflags” paired with “hintsetup” enables hardware interrupts that run in the background and don’t need to be polled to check their status. Polled interrupts and hardware interrupts essentially work the same but have different routes to set up.

FWIW I tried using a polled interrupt on pinC.1 at some point between fits of headbanging and the results were the same.

As far as reactivating the interrupt, I don’t do it within the interrupt subroutine itself but after it exits and starts from the beginning of the code. IIRC it will still enable the interrupt whether it’s in the interrupt section or elsewhere.

Thank you for giving my code the magnifying glass! The more eyes the better.

I’m a picaxe noob

I’m a picaxe noob but:

http://www.picaxe.com/BASIC-Commands/Advanced-PICAXE-Configuration/hintsetup/

it says: Bit 0 - Interrupt 0 Enable (not available on 20X2).

never mind, youre using bit 1. mistake.

Instead of this whole

Instead of this whole interrupt driven program, can’t it be done just like this:

  1. Low pin for 10ms and make it high again.
  2. Then pause for a fixed delay (as long as the sonar is busy + the 10ms after that)
  3. Measure how long it takes before the input pin goes high.