I know this is crazy, but this is what is happening and it definitely does not make any sense. I have one IR Range sensor reading on three different ADC inputs - AX0, AX1, and AX2. I have verified all my cable connections. I have verified that I can read each ADC separately by connecting one sensor to each one and running a test that reads just that ADC. I did this for AX0, AX1, and AX2, and the same sensor reads on each ADC no matter what I do. I have three different sensors plugged into these ADCs and I can only read the same sensor on each one of them.
How can this possibly be true? I verified this twice to be absolutely sure this is what is happening and it is.
I’m not sure there is any other way to restate my problem where it makes more sense.
I have 3 Sharp GP2D12 IR Sensors plugged into the AX0, AX1, and AX2 Analog Inputs. Each of these ADCs reads the same sensor no matter what I do. I can not get a reading from any other sensor no matter what I do. It is always the same sensor that works for all three ADCs.
I don’t think I can state it any more clear than that.
I did a quick look at the Pic16F87 manual and it sortof looks like there is one set of AtoD hardware, although it can switch from several different inputs. I will be trying something similar on my Hex, but I will be using the PRO which has 8 AtoD inputs and the command is much simpler. Just a command like:
ADIN P19, myval
Have you tried pauses inbetween? I know that on some other machine (which I don’t remember which one), I had to do something like:
Just for the fun of it, I had a spare ABB with an Atom and a couple of Sharp sensors available so I tried several combinations and like you it failed to get inputs from both AtoD inputs.
I then hooked up the two sharp sensors to one of the Atom Pro boards and the following program was sucessful in reading the inputs.
wIgnore var word
w0 var word
w1 var word
w0Last var word
w1Last var word
;-------------Init
clear
;-------------Main loop
main
ADIN p0, w0
ADIN p1, w1
if w0 <> w0Last or w1 <> w1Last then
serout S_OUT, I9600, "W0=", dec w0, " W1= ", dec w1, 13]
w0Last = w0
w1Last = w1
pause 500
endif
goto main
Again I am not sure if this helps, but it does give you another datapoint.
I have tried a scheme like Jim had me do for the IRPD, where I read a sensor 5 times and only take the fifth reading sort of thing. That did not give me any different results.
I also tried pauses at the end of the loop where I read the sensors, and that didn’t give me anything different either.
I am out of ideas, and am starting to wonder if two of my sensors could have gone bad. If so, I don’t know how it could have happened. I still have the one sensor masquerading as all three and not all the time. Sometimes it is sensor 1 and sometimes it is sensor 3, and other times it is just itself or all three. Very weird.
The current code I am dealing with is:
[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 3 ’ Wheel Left
IR_RW con 4 ’ 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
’
’ IR Rangers
’
IR_Distance var word(5) ’ Distance object was detected at
IR_Detected var bit(5) ’ Was object detected? 0 = No, 1 = Yes
IR_Threshold var word(5) ’ Detection threshold for each IR Ranger
IR_Offset var sbyte(5) ’ Offset to threshold distance for detection
IR_Status var word ’ IR Detection status - 1 = Left Front, 2 = Right Front, 3 = BOTH Front, 4 = Turret IR
’ 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 AX1, 2, AD_RON, scanrange
elseif index = IR_TU ' Pan/Tilt Turret
adin AX2, 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
Invalid_Sensor:
if sendoutput then
serout S_OUT, I8N1_2400, “----------------------------------------------------------------------”, 10, 13]
endif
return
’ Check only the IR Ranger on the Pan/Tilt Turret
Check_IR_Turret:
IR_Status = 0
’ IR_Status = (IR_Status AND %11111011) ’ Zero the status bit
IR_Detected(IR_TU) = 0
servo tilt, -50
' Read the sensor value
for loop = 1 to 4
adin AX2, 2, AD_RON, scanrange
next
tfloat = TOFLOAT scanrange / 5.12 ' Limit value to < 200 values
IR_Distance(IR_TU) = scantable(TOINT tfloat) ' Convert A/D to measurement
if (scanrange > 512) OR (IR_Distance(IR_TU) < (IR_Threshold(IR_TU) + IR_Offset(IR_TU))) then
IR_Detected(IR_TU) = 1
IR_Status = IR_Status + IR_Turret
endif
if IR_Detected(IR_TU) AND makenoise then
sound speaker, [dur\note9,dur\note10,dur\note11,dur\note12]
endif
return[/code]
The only sensor I can get any reading from at all is the Left Front sensor on AX0.
I maybe should have been more careful in my earlier response . When I said another machine, it was also a different microcontroller. On my Atom with two of these sensors I am also getting bad results the same as your. When I tried it on the Pro, the two appeared to work fine.
Dang. My problem is with the newer v5.3.0.1 IDE too. I upgraded to get another known issue solved. I may have to step up my switch to PICs programmed in C - I just need to get a good programmer and the rest of the parts to build one of Pete’s (sapian59) boards.
Yes, he offered me a tentative exchange, but I have not called him to discuss it.
At that time I was not interested in exchanging because there is a lot I can still do with the Basic ATOM. The correct solution to this would be to fix the existing problem, where ever it might end up being, and I am willing to help isolate it more if that can be done.
However, I am getting a bit tired of running into problems like this. If this problem turns out to be a hardware issue with the Basic ATOM, I am willing to discuss a trade up. I would release the version of the code I have now as v1.41 as I believe it is correct, then convert it over to the ATOM PRO and continue developing from there.
This does sound like a bug in the new Atom compiler. Give me a call Monday. I’ll setup a test and check it. If it is a bug I’ll fix it and get a new release up.
P.S. The hardware tradin option was because it sounded like you needed the performance increase the PRO would give. The A/D hardware on the Atom works fine(has for 5 years). The new software release(with a lot of changes) probably borked something we didn’t catch. It’s not a hardware issue(atleast not an Atom hardware issue).
Found the bug. In the mbasicadin.lib file(the directory should be C:\Program Files\BasicMicro Inc\BasicAtom IDE\system\MBasic14) you need to add the three lines of code that I’ve marked in the ADIN_INIT subroutine.
[code]_ADIN_INIT
clrf ADCON0 ; Reset ADCON0
bsf ADCON0,0 ; Enable A/D converter
movfw _ADIN_SETUP
_@BANK _WORK,ADCON1 ; Sel ADCON1 bank
movwf ADCON1&0x7f ; Load ADCON1
_@BANK ADCON1,_WORK ; Sel WORK bank
_@CALL _GETPIN ;Add this line
movfw _STACK+1 ;Add this line
movwf _ADIN_PIN ;Add this line
clrf _ADIN_WORK
_@ADCHANNEL _ADIN0,b'00000000'
_@ADCHANNEL _ADIN1,b'00001000'
_@ADCHANNEL _ADIN2,b'00010000'
_@ADCHANNEL _ADIN3,b'00011000'
_@ADCHANNEL _ADIN4,b'00100000'
_@ADCHANNEL _ADIN5,b'00101000'
_@ADCHANNEL _ADIN6,b'00110000'
_@ADCHANNEL _ADIN7,b'00111000'
_@ADCHANNEL _ADIN8,b'00000010'
_@ADCHANNEL _ADIN9,b'00001010'
movfw _ADIN_WORK ; Get Channel
iorwf ADCON0,f ; IOR ADCON0
[/code]
The pin number wasn’t being properly handled in the ADIN command. The three lines of code fix that problem. I’ll probably have a new update up sometime next week.