Basic ATOM Code for the Sharp GP2D12 IR Range Sensor

Here is my routine to read any number of the GP2D12 IR Range Sensors. This is the code I wrote for W.A.L.T.E.R. which is based on some code I found here. I’ll answer any questions that may come up about this code here.

[code]’
’ IR Ranging Configuration

IR_Max con 3 ’ How many IR Rangers we have
IR_Threshld_Dist con 25 ’ Distance Threshold in cm for Turret closeness checks
IR_Threshld_Frnt con 35 ’ Front Detection threshold in cm
IR_Threshld_Tur con 35 ’ Detection threshold for Pan/Tilt Turret IR Ranger

’ IR Sensor Numbers

IR_LF con 0 ’ Left Front
IR_RF con 1 ’ Right Front
IR_TU con 2 ’ Pan/Tilt Turret
’ Future expansion
IR_LW con 4 ’ Wheel Left
IR_RW con 8 ’ Wheel Right

’ Bits for IR_Status checking

IR_LeftFront con 1
IR_RightFront con 2
IR_BothFront con 3
IR_Turret con 4
’ For future expansion
IR_LeftWheel con 8 ’ Left Side (across wheel)
IR_RightWheel con 16 ’ Right Side (across wheel)
IR_BothWheels con 24 ’ Both Sides (across wheels)

'---- Table Setup for IR Ranging Routine ] ----------------------------------------------------------

scantable bytetable 80,80,80,80,80,80,80,80,80,78, |
76,74,72,70,68,66,64,62,60,59, |
58,57,55,53,52,51,50,49,48,47, |
45,43,42,41,40,39,38,37,35,33, |
32,31,30,30,29,29,28,28,27,27, |
26,26,26,25,25,25,24,24,24,23, |
23,22,22,21,21,20,20,20,19,19, |
18,18,18,17,17,16,16,16,15,15, |
15,14,14,13,13,13,12,12,11,11, |
11,10,10,10,10,10,10,10,10,10

’ Read up to three IR Ranging sensors - based on code written by Nathan Scherdin
’ and Chuck Hellebuyck in their Range.Bas module. This routine can read up to
’ three IR Rangers without modification, controlled by the constant IR_Max.
Check_IR_Rangers:
IR_Status = 0

for index = 0 to IR_Max - 1
	IR_Detected(index) = 0
	
	' Read the sensor value
		if index = IR_LF then									' Left Front
			adin AX0, 2, AD_RON, scanrange
		elseif index = IR_RF									' Right Front
			adin AX2, 2, AD_RON, scanrange
		elseif index = IR_TU									' Pan/Tilt Turret
			adin AX3, 2, AD_RON, scanrange
		else
			if sendoutput then
				serout S_OUT, I8N1_2400, "Invalid sensor number - ", DEC index, "!", 10, 13]
			endif
		
			exception Invalid_Sensor
		endif

	if sendoutput then
		serout S_OUT, I8N1_2400, "Check_IR_Rangers: index = ", DEC index, ", IRPD_Status = ", DEC IRPD_Status, ", IR_Status = ", DEC IR_Status, 10, 13]
	endif

	tfloat = TOFLOAT scanrange / 5.12						' Limit value to < 200 values
	IR_Distance(index) = scantable(TOINT tfloat)			' Convert A/D to measurement
	
	if (scanrange > 512) OR (IR_Distance(index) < (IR_Threshold(index) + IR_Offset(index))) then
		IR_Detected(index) = 1
	
		' Add bit value for the current sensor to IR_Status
		'	Bit 0 = 1, Sensor 0 Detect		0 0 0 0 0 0 0 1 Left Side
		'	Bit 1 = 1, Sensor 1 Detect		0 0 0 0 0 0 1 0 Right Side
		'	Bit 2 = 1, Sensor 2 Detect		0 0 0 0 0 1 0 0 Turret
		'	Bit 3 = 1, Sensor 3 Detect		0 0 0 0 1 0 0 0 Left Wheel
		'	Bit 4 = 1, Sensor 4 Detect		0 0 0 1 0 0 0 0 Right Wheel
		if index = IR_LF then	
			IR_Status = IR_Status + 1
		else
			' This will have to be changed for more than 3 sensors - need proper
			'	power of 2 routine to make this code truely expandable.
			IR_Status = IR_Status + (index * 2)
		endif
		
		if makenoise then	
			if index = IR_LF then						' Front Left Side
				sound speaker, [dur\note5,dur\note6,dur\note7,dur\note8]
			elseif index = IR_RF						' Front Right Side
				sound speaker, [dur\note8,dur\note7,dur\note6,dur\note5]
			elseif index = IR_TU						' Turret
				sound speaker, [dur\note9,dur\note10,dur\note11,dur\note12]
			endif
		endif
	endif

	if sendoutput then
		serout S_OUT, I8N1_2400, "Check_IR_Rangers: index = ", DEC index, ", Threshold = ", DEC IR_Threshold(index), ", Distance = ", DEC IR_Distance(index), " cm, Detected = ", DEC IR_Detected(index), 10, 13]
	endif
next

if sendoutput then
	serout S_OUT, I8N1_2400, "Check_IR_Rangers: --------------------------------------------------------------------------------------------", 10, 13]
endif

Invalid_Sensor:
return[/code]

8-Dale

Is this code for the regular Atom 28 or Pro? I’m guessing Atom 28 based on what I’ve read about Walter elsewhere.

I’m asking because I’m ready to buy, but I’m still trying to decide on which Atom to start out with. I’d really like to go for the Pro, since it’s “better”, but if all this great software won’t run as-is then I’ll have to start with the Atom 28…

Or maybe one of the gurus can test/modify this to work on the Atom Pro and post it for us?

Thanks!

The current code for WALTER, and all that I have written so far, is for the Basic Atom. As soon as I can, it will all be converted to run on the Atom PRO. I will do all new development for the Atom PRO.

It’s all a learning process. Are you planning to write your own code at some point? If you are, then I recommend going right to the Atom PRO. The Atom PRO has twice the memory, is much faster, and has some hardware features (hardware serial port, hardware PWM for servos) the Basic Atom does not have . I already ran out of memory on the Basic Atom.

Which ever one you choose, get the starter kit with the manual, bot board, and such. It’s worth the price.

8-Dale

That’s good to know. I’ll be watching for your posts. :smiley:

That sounds like good advice. I’m a programmer with 10 years of professional experience, and before that I had been programming as a hobby since middle school. I think I can do some things on the software side once I grok the robotics metaphors and learn more about electronics.

I’m going to go place an order on lynxmotion.com now because I can’t stand to be botless any longer!

I predict that you will have no problems getting into programming the Basic Atom or Atom PRO, whichever one you decide to get. I’ve been out of programming for awhile, but have not had any problems getting back into it with the Atoms.

Now I’m getting back into working in Python also, which is one of my favorite programming languages. As soon as I have a good and inexpensive way to read sensor data using Python, I plan to code more robotics and robot software with it. I’ve already demonstrated how to control the SSC-32 (bi-directional communication) using Python. :smiley:

Which microcontroller are you getting? Which robot are you going to build?

8-Dale

I don’t want to hijack your excellent code thread, so I’ll kick this back to my newbie thread here:
lynxmotion.net/viewtopic.php?t=1934

This is the code I use, based on the linear transform on the acroname site acroname.com/robotics/info/a … inear.html
Gives readings in cm (approx) for two versions of the sensor and saves the RAM used for a lookup table…
-Drew

; test of sharp GP2D12(0) sensors
; based on code from acroname site
;
; Drew Weng
; For BasicATOM Pro

; pin constants
ir_fl con p0
ir_fr con p1
ir_fc con p2

; raw 10-bit val from A/D
ir_fl_val var word
ir_fr_val var word
ir_fc_val var word

; converted range in cm
ir_fl_rng var byte
ir_fr_rng var byte
ir_fc_rng var byte

main

adin ir_fl, ir_fl_val
adin ir_fr, ir_fr_val
adin ir_fc, ir_fc_val

;For GP2D12 R = (6787 / (V - 3)) - 4
;For GP2D120 R = (2914 / (V + 5)) - 1

If ir_fr_val > 3 then
ir_fr_rng = (6787 / (ir_fr_val - 3)) - 4
else
ir_fr_rng = 999
endif

If ir_fl_val > 3 then
ir_fl_rng = (6787 / (ir_fl_val - 3)) - 4
else
ir_fl_rng = 999
endif

ir_fc_rng = (2914 / (ir_fc_val + 5)) - 1

debug [dec ir_fl_rng ]
debug ", " ]
debug [dec ir_fr_rng ]
debug ", " ]
debug [dec ir_fc_rng ]
debug 13 ]

pause 500

goto main

This is the code I use, based on the linear transform on the acroname site acroname.com/robotics/info/a … inear.html
Gives readings in cm (approx) for two versions of the sensor and saves the RAM used for a lookup table…
-Drew

; test of sharp GP2D12(0) sensors
; based on code from acroname site
;
; Drew Weng
; For BasicATOM Pro

; pin constants
ir_fl con p0
ir_fr con p1
ir_fc con p2

; raw 10-bit val from A/D
ir_fl_val var word
ir_fr_val var word
ir_fc_val var word

; converted range in cm
ir_fl_rng var byte
ir_fr_rng var byte
ir_fc_rng var byte

main

adin ir_fl, ir_fl_val
adin ir_fr, ir_fr_val
adin ir_fc, ir_fc_val

;For GP2D12 R = (6787 / (V - 3)) - 4
;For GP2D120 R = (2914 / (V + 5)) - 1

If ir_fr_val > 3 then
ir_fr_rng = (6787 / (ir_fr_val - 3)) - 4
else
ir_fr_rng = 999
endif

If ir_fl_val > 3 then
ir_fl_rng = (6787 / (ir_fl_val - 3)) - 4
else
ir_fl_rng = 999
endif

ir_fc_rng = (2914 / (ir_fc_val + 5)) - 1

debug [dec ir_fl_rng ]
debug ", " ]
debug [dec ir_fr_rng ]
debug ", " ]
debug [dec ir_fc_rng ]
debug 13 ]

pause 500

goto main