Hello, sorry to keep bothering you guys with these questions:
I want to make a simple line following robot, using some LED IR emitter and detectors. I want to use a PIC 16F628A or 16F684. I really have no idea how to get started -- but hopefully there will be some kind of tutorial someone can point me to, or give me some information.
I really have no clue how to set up the emitter and detector to detect the line -- is it even possible?
Thanks
Omar
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I'd recommend that you use the 16F684, as it has an A/D converter in it that will make reading the sensors much easier.
From personal experience, it is better to use visible LEDs and LDRs or phototransistors to detect the line. Because the light is visible, it is easier to see if everything is aligned properly.
Thank you very much for that. I checked out the information, and it helped a lot. Now I have a few questions:
The code you gave me from the demo files, is for a specific robot kit, and frankly I'd rather build my own, so would you by any chance have code snippets of a line detecting program in Great Cow Basic? Pretty please? I actually like this method better (CDS cell and LED), and it seems that calibrating would be easier.
As for the chip, that is no problem. In fact I accidentally bought a few of those chips anyway so it seems it'll work out. Yay for not wasting micro controllers =D
Now any ideas how I can drive a motor from the pins? It seems not enough current is being supplied... and I have heard I need some kind of driver. I think the author of the linked tutorial isn't using a driver, how can he get away with it?
Thanks a lot, your help means a lot!
Omar
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Okay, well I have tried to figure stuff out on my own -- I don't want to bug you for everything. So here is how far I have gotten. I have decided to use the IR detector and sensor for now, as it seems easier to program.
-----------------------------------
#chip 16F684, 8
dir PORTC.0 OUT
dir PORTC.1 OUT
dir PORTC.2 IN
dir PORTA.0 IN
'Put the sensor on the right side of the line
SET PORTC.0 ON
SET PORTC.1 ON
Start:
IF ReadAD (PORTA.0) > 3.5 THEN
SET PORTC.1 ON
SET PORTC.0 OFF
IF ReadAD (PORTA.0) > 3.5 THEN
SET PORTC.0 ON
SET PORTC.1 OFF
goto Start
--------------------------
PORTC.0 is my right motor
PORTC.1 is my left motor
I use the readAD function to get the measurement from the detector. Basically, you set it on the right side of the line (the robot's detector), and the robot starts to go left, as soon as it detects white space, it turns right, and then it follows that pattern. Of course, it isn't that snazzy -- quite static actually. But I think it may be simple enough to work. Can you spot and obvious errors in my code?
As for the motor, I tried using the motor driver that http://www.diylive.net/index.php/2005/12/13/diy-line-following-robot2/ the author made (schematics posted in the article). It seems to make my motor run, but when I was testing it with simple on/off code, the timing was going crazy. Such as the motor is supposed to turn on for 10 seconds, and then turn off, while another pin turns on at this point. But the motor would stay on for 3 seconds, and the other pin for the rest of the time. Could it be feedback from the motor messing up the microcontroller? Do you recommend anything to fix this??
Thanks for your help!
Omar
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
- It is trying to use the HS oscillator. This may be okay, but if you are trying to use the internal oscillator of the chip, you should add this line:
#config INTRC_OSC_NOCLKOUT
- ReadAD accepts AN0, AN1, AN2, etc as parameters. PORTA.0 would be confusing it completely - replace PORTA.0 with AN0 and it will be fine
- GCBASIC cannot handle floating point numbers, so 3.5 would be confusing it. Change it to 3 or 4.
- You need END IF at the end of the IF statements.
I can't help you much with the hardware side of things - all I can recommend is that you have plenty of capacitors on the power supply pins of the PIC, and on each of the motors.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Aside from all of those, will it get confused that after the first initial going left-until-off-the-line, that it has to now go the other way until-off-the-line... will that cause a confusion?
This is what I have so far, fixed. As for the hardware-- took your advice. Thank you!
dir PORTC.0 OUT
dir PORTC.1 OUT
dir PORTC.2 OUT
dir PORTA.0 IN
'Put the sensor on the right side of the line
SET PORTC.1 OFF
SET PORTC.0 ON
Start:
DO UNTIL ReadAD (AN0) > 3
SET PORTC.1 ON
SET PORTC.0 OFF
LOOP
IF ReadAD (AN0) > 3 THEN
SET PORTC.1 OFF
SET PORTC.0 ON
DO UNTIL ReadAD (AN0) > 3
SET PORTC.1 OFF
SET PORTC.0 ON
LOOP
goto Start
--------
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
dir PORTC.0 OUT
dir PORTC.1 OUT
dir PORTC.2 OUT
dir PORTA.0 IN
'Put the sensor on the right side of the line
SET PORTC.1 OFF
SET PORTC.0 ON
Start:
DO UNTIL ReadAD (AN0) > 3
SET PORTC.1 ON
SET PORTC.0 OFF
LOOP
IF ReadAD (AN0) > 3 THEN
SET PORTC.1 OFF
SET PORTC.0 ON
DO UNTIL ReadAD (AN0) > 3
SET PORTC.1 OFF
SET PORTC.0 ON
LOOP
END IF
goto Start
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Your code should work, try compiling and running it and see what happens.
One thing that you could do to make the code easier to read is use indentation, like this:
DO UNTIL ReadAD (AN0) > 3
SET PORTC.1 ON
SET PORTC.0 OFF
LOOP
IF ReadAD (AN0) > 3 THEN
SET PORTC.1 OFF
SET PORTC.0 ON
DO UNTIL ReadAD (AN0) > 3
SET PORTC.1 OFF
SET PORTC.0 ON
LOOP
END IF
This makes it much easier to see if you have left out an END IF.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I am sorry. I've started to indent my code it does truly help. Just when I post it here the indents seem to disappear. I've decided to fix he code a little, and I've even made a calibration system so I can get the exact readings. If you don't mind, could you please look over it again? I copied the line following code and changed it a bit as per one of the demo files that were supplied.
Thank you very much (I'll repost with just the code, so it is easier to see).
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
dir PORTC.0 OUT
dir PORTC.1 OUT
dir PORTC.4 OUT
dir PORTA.0 IN
dir PORTC.3 IN
dir PORTC.2 IN
IF PORTC.3 ON THEN CALIBRATE
WAIT UNTIL PORTC.2 ON
EPRead (0, LINEo)
EPRead (1, LINEof)
SET PORTC.1 OFF
SET PORTC.0 ON
START:
IF ReadAD (AN0) >= LINEo THEN LEFT
IF ReadAD (AN0) <= LINEof THEN RIGHT
GOTO START
SUB LEFT
SET PORTC.1 OFF
SET PORTC.0 ON
END SUB
SUB RIGHT
SET PORTC.1 ON
SET PORTC.0 OFF
END SUB
SUB CALIBRATE
WAIT UNTIL PORTC.2 ON
IF PORTC.2 ON THEN ReadingOne = ReadAD (AN0)
WAIT UNTIL PORTC.2 ON
IF PORTC.2 ON THEN ReadingTwo = ReadAD (AN0)
WAIT UNTIL PORTC.2 ON
IF PORTC.2 ON THEN ReadingThree = ReadAD (AN0)
WAIT UNTIL PORTC.2 ON
IF PORTC.2 ON THEN ReadingFour = ReadAD (AN0)
wait 1 s
Reado = (ReadingOne + ReadingTwo) / 2
Readt = (ReadingThree + ReadingFour) / 2
EPWrite (0, Reado)
EPWrite (1, Readt)
wait 1 s
SET PORTC.4 ON
wait 1 s
SET PORTC.4 OFF
WAIT UNTIL PORTC.2 ON
EXIT
END SUB
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
It looks pretty good, and should be okay except for two things. First, the EXIT on the second to last line doesn't say what to exit from.
Also, there is an undocumented Average function that you could use instead of the division. It will run faster and use less code, plus it won't cause problems if the total of the two values exceeds 255. To use it, replace
Oh, thank you very much! I was just wondering, do I need that exit function in that Calibration Sub, or will it automatically exit and go back to the part of code where it left of?
That average function will really save me some headaches, I'm sure I would have gone insane when the line follower doesn't correctly work.
One more thing, I didn't think that code above would work (the line following part) so I changed it to this. I'm not sure, logically both might work but I am leaning towards this one. Any ideas?
START:
DO WHILE ReadAD (AN0) >= LINEo
SET PORTC.1 OFF
SET PORTC.0 ON
LOOP
IF ReadAD (AN0) <= LINEof
SET PORTC.1 OFF
SET PORTC.0 ON
DO UNTIL ReadAD (AN0) <= LINEof
SET PORTC.1 OFF
SET PORTC.0 ON
LOOP
END IF
IF ReadAD (AN0) <= LINEof
SET PORTC.1 ON
SET PORTC.0 OFF
END IF
GOTO START
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Just one more question, will it matter if I decide to wait a few seconds between each calibration and button press-- will the value of the variable keep changing... like:
WAIT UNTIL PORTC.2 ON
IF PORTC.2 ON THEN ReadingOne = ReadAD (AN0)
SET PORTC.4 OFF
WAIT 2 s
SET PORTC.4 ON
WAIT UNTIL PORTC.2 ON
IF PORTC.2 ON THEN ReadingTwo = ReadAD (AN0)
SET PORTC.4 OFF
WAIT 2 s
SET PORTC.4 ON
If I press the button, the variable value becomes the sensor reading. Now at this point the program flashes LEDs to tell me it worked so far... during that time if the sensor readings change does that mean the variable will keep on changing too?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
i recommend using 3 sensors with the following algorithm pseudo code, i won the national titles with this(note this is pseudo code not gcbasic because i originally programmed in assember):
if left sensor detects line:
turn right until middle sensor detects it
if right sensor detects line:
turn left until middle sensor detects line
this way, if the motor is going fast and by the time the line is detected its already over the line, it will just turn until it is found! , theoretically, no matter how fast you are going, you should still catch the line.
ps: i suggest writing the calibration values to the onboard eeprom since this cant be reset to a pin value.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I have been doing experiments with a IR light sensor ( I bought a pack of IR emitter and IR detector from SparkFun for $2 part number SEN-00241)... That site has a link to basic circuitry for this IR detector.
I have been doing some experimentation with sensing light using this detector.
I have used the following code as a testbed for sensing and logging the data to the EEPROM in the chip (16F887). I then use the Read Chip feature in the MPLAB IDE to see the data stored in the EEPROM.
Hope this helps.
'Define Chip Model and its operating frequency in MHz
#chip 16F887, 4
'Define the Port Pin Assignments and my Descriptions
#define MaintStatus PORTD.1 'Pin function RD1 as the cpu signal to show with Green Steady LED when in maintenance mode
#define Activity PORTD.2 'Pin function RD2 as the cpu signal to show with Red Blinking LED of Activity
#define InActive PORTD.3 'Pin function RD3 as the cpu signal to show with Green Blinking LED if Inactive
'Analog PORT Definitions / Functions
#define PLightMeter PORTA.0 'Pin 2 (RA0/AN0) function AN0 as the sensor to detect the light level
'Define Analog Port Pin Functions
#define LightMeter AN0
'Other definitions
#define half_sec 50 10ms
'Set the Port Pin Directions
DIR MaintStatus OUT
DIR Activity OUT
DIR InActive OUT
DIR PLightMeter IN
'------------------- MAIN LOGIC -------------------
SUB set_ports
' Set OUT ports to OFF
SET MaintStatus OFF
SET Activity OFF
SET InActive OFF
END SUB
SUB lead_in_warning
'Indicate sampling is about to start
FOR Data_count = 1 TO 10
SET InActive ON 'Green
SET Activity ON 'Red
WAIT half_sec
SET InActive OFF 'Green
SET Activity OFF 'Red
WAIT half_sec
NEXT
END SUB
SUB measure_light_level (From_data, To_data) #NR
'Do twenty lightmeter readings
FOR Data_count = From_data TO To_data
SET Activity ON 'Red
WAIT half_sec
SET Activity OFF 'Red
'Do Measurement
Light_level = ReadAD(LightMeter)
EP_mem_addr = Data_count - 1 'eeprom addresses start at zero.
EPWrite(EP_mem_addr, Light_level)
NEXT
END SUB
SUB completion_lights
SET MaintStatus ON 'Green
SET InActive ON 'Green
END SUB
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hello, sorry to keep bothering you guys with these questions:
I want to make a simple line following robot, using some LED IR emitter and detectors. I want to use a PIC 16F628A or 16F684. I really have no idea how to get started -- but hopefully there will be some kind of tutorial someone can point me to, or give me some information.
I really have no clue how to set up the emitter and detector to detect the line -- is it even possible?
Thanks
Omar
Some links:
http://www.fastcharged.org/robotics/firstrobot
http://www.diylive.net/index.php/2005/12/13/diy-line-following-robot2/
I'd recommend that you use the 16F684, as it has an A/D converter in it that will make reading the sensors much easier.
From personal experience, it is better to use visible LEDs and LDRs or phototransistors to detect the line. Because the light is visible, it is easier to see if everything is aligned properly.
For the programming code, have a look at http://gcbasic.sourceforge.net/newfiles/analog%20line.txt
Thank you very much for that. I checked out the information, and it helped a lot. Now I have a few questions:
The code you gave me from the demo files, is for a specific robot kit, and frankly I'd rather build my own, so would you by any chance have code snippets of a line detecting program in Great Cow Basic? Pretty please? I actually like this method better (CDS cell and LED), and it seems that calibrating would be easier.
As for the chip, that is no problem. In fact I accidentally bought a few of those chips anyway so it seems it'll work out. Yay for not wasting micro controllers =D
Now any ideas how I can drive a motor from the pins? It seems not enough current is being supplied... and I have heard I need some kind of driver. I think the author of the linked tutorial isn't using a driver, how can he get away with it?
Thanks a lot, your help means a lot!
Omar
Okay, well I have tried to figure stuff out on my own -- I don't want to bug you for everything. So here is how far I have gotten. I have decided to use the IR detector and sensor for now, as it seems easier to program.
-----------------------------------
#chip 16F684, 8
dir PORTC.0 OUT
dir PORTC.1 OUT
dir PORTC.2 IN
dir PORTA.0 IN
'Put the sensor on the right side of the line
SET PORTC.0 ON
SET PORTC.1 ON
Start:
IF ReadAD (PORTA.0) > 3.5 THEN
SET PORTC.1 ON
SET PORTC.0 OFF
IF ReadAD (PORTA.0) > 3.5 THEN
SET PORTC.0 ON
SET PORTC.1 OFF
goto Start
--------------------------
PORTC.0 is my right motor
PORTC.1 is my left motor
I use the readAD function to get the measurement from the detector. Basically, you set it on the right side of the line (the robot's detector), and the robot starts to go left, as soon as it detects white space, it turns right, and then it follows that pattern. Of course, it isn't that snazzy -- quite static actually. But I think it may be simple enough to work. Can you spot and obvious errors in my code?
As for the motor, I tried using the motor driver that http://www.diylive.net/index.php/2005/12/13/diy-line-following-robot2/ the author made (schematics posted in the article). It seems to make my motor run, but when I was testing it with simple on/off code, the timing was going crazy. Such as the motor is supposed to turn on for 10 seconds, and then turn off, while another pin turns on at this point. But the motor would stay on for 3 seconds, and the other pin for the rest of the time. Could it be feedback from the motor messing up the microcontroller? Do you recommend anything to fix this??
Thanks for your help!
Omar
Sorry, not meaning to bump for no reason, but does anyone have any replies for that last post?
There are several problems with your program:
- It is trying to use the HS oscillator. This may be okay, but if you are trying to use the internal oscillator of the chip, you should add this line:
#config INTRC_OSC_NOCLKOUT
- ReadAD accepts AN0, AN1, AN2, etc as parameters. PORTA.0 would be confusing it completely - replace PORTA.0 with AN0 and it will be fine
- GCBASIC cannot handle floating point numbers, so 3.5 would be confusing it. Change it to 3 or 4.
- You need END IF at the end of the IF statements.
I can't help you much with the hardware side of things - all I can recommend is that you have plenty of capacitors on the power supply pins of the PIC, and on each of the motors.
Aside from all of those, will it get confused that after the first initial going left-until-off-the-line, that it has to now go the other way until-off-the-line... will that cause a confusion?
This is what I have so far, fixed. As for the hardware-- took your advice. Thank you!
--------
#chip 16F684, 8
#config INTRC_OSC_NOCLKOUT
dir PORTC.0 OUT
dir PORTC.1 OUT
dir PORTC.2 OUT
dir PORTA.0 IN
'Put the sensor on the right side of the line
SET PORTC.1 OFF
SET PORTC.0 ON
Start:
DO UNTIL ReadAD (AN0) > 3
SET PORTC.1 ON
SET PORTC.0 OFF
LOOP
IF ReadAD (AN0) > 3 THEN
SET PORTC.1 OFF
SET PORTC.0 ON
DO UNTIL ReadAD (AN0) > 3
SET PORTC.1 OFF
SET PORTC.0 ON
LOOP
goto Start
--------
Sorry, forgot one END IF...
#chip 16F684, 8
#config INTRC_OSC_NOCLKOUT
dir PORTC.0 OUT
dir PORTC.1 OUT
dir PORTC.2 OUT
dir PORTA.0 IN
'Put the sensor on the right side of the line
SET PORTC.1 OFF
SET PORTC.0 ON
Start:
DO UNTIL ReadAD (AN0) > 3
SET PORTC.1 ON
SET PORTC.0 OFF
LOOP
IF ReadAD (AN0) > 3 THEN
SET PORTC.1 OFF
SET PORTC.0 ON
DO UNTIL ReadAD (AN0) > 3
SET PORTC.1 OFF
SET PORTC.0 ON
LOOP
END IF
goto Start
I'm sorry to bump, but I was wondering if that above code would work?
Thanks for your help, I'm sorry to bump like this but I thought my post was forgotten.
Your code should work, try compiling and running it and see what happens.
One thing that you could do to make the code easier to read is use indentation, like this:
DO UNTIL ReadAD (AN0) > 3
SET PORTC.1 ON
SET PORTC.0 OFF
LOOP
IF ReadAD (AN0) > 3 THEN
SET PORTC.1 OFF
SET PORTC.0 ON
DO UNTIL ReadAD (AN0) > 3
SET PORTC.1 OFF
SET PORTC.0 ON
LOOP
END IF
This makes it much easier to see if you have left out an END IF.
I am sorry. I've started to indent my code it does truly help. Just when I post it here the indents seem to disappear. I've decided to fix he code a little, and I've even made a calibration system so I can get the exact readings. If you don't mind, could you please look over it again? I copied the line following code and changed it a bit as per one of the demo files that were supplied.
Thank you very much (I'll repost with just the code, so it is easier to see).
#chip 16F684, 8
#config INTRC_OSC_NOCLKOUT
ReadingOne = 0
ReadingTwo = 0
ReadingThree = 0
ReadingFour = 0
Reado = 0
Readt = 0
LINEo = 0
LINEof = 0
dir PORTC.0 OUT
dir PORTC.1 OUT
dir PORTC.4 OUT
dir PORTA.0 IN
dir PORTC.3 IN
dir PORTC.2 IN
IF PORTC.3 ON THEN CALIBRATE
WAIT UNTIL PORTC.2 ON
EPRead (0, LINEo)
EPRead (1, LINEof)
SET PORTC.1 OFF
SET PORTC.0 ON
START:
IF ReadAD (AN0) >= LINEo THEN LEFT
IF ReadAD (AN0) <= LINEof THEN RIGHT
GOTO START
SUB LEFT
SET PORTC.1 OFF
SET PORTC.0 ON
END SUB
SUB RIGHT
SET PORTC.1 ON
SET PORTC.0 OFF
END SUB
SUB CALIBRATE
WAIT UNTIL PORTC.2 ON
IF PORTC.2 ON THEN ReadingOne = ReadAD (AN0)
WAIT UNTIL PORTC.2 ON
IF PORTC.2 ON THEN ReadingTwo = ReadAD (AN0)
WAIT UNTIL PORTC.2 ON
IF PORTC.2 ON THEN ReadingThree = ReadAD (AN0)
WAIT UNTIL PORTC.2 ON
IF PORTC.2 ON THEN ReadingFour = ReadAD (AN0)
wait 1 s
Reado = (ReadingOne + ReadingTwo) / 2
Readt = (ReadingThree + ReadingFour) / 2
EPWrite (0, Reado)
EPWrite (1, Readt)
wait 1 s
SET PORTC.4 ON
wait 1 s
SET PORTC.4 OFF
WAIT UNTIL PORTC.2 ON
EXIT
END SUB
It looks pretty good, and should be okay except for two things. First, the EXIT on the second to last line doesn't say what to exit from.
Also, there is an undocumented Average function that you could use instead of the division. It will run faster and use less code, plus it won't cause problems if the total of the two values exceeds 255. To use it, replace
Reado = (ReadingOne + ReadingTwo) / 2
Readt = (ReadingThree + ReadingFour) / 2
with
Reado = Average(ReadingOne, ReadingTwo)
Readt = Average(ReadingThree, ReadingFour)
Oh, thank you very much! I was just wondering, do I need that exit function in that Calibration Sub, or will it automatically exit and go back to the part of code where it left of?
That average function will really save me some headaches, I'm sure I would have gone insane when the line follower doesn't correctly work.
One more thing, I didn't think that code above would work (the line following part) so I changed it to this. I'm not sure, logically both might work but I am leaning towards this one. Any ideas?
START:
DO WHILE ReadAD (AN0) >= LINEo
SET PORTC.1 OFF
SET PORTC.0 ON
LOOP
IF ReadAD (AN0) <= LINEof
SET PORTC.1 OFF
SET PORTC.0 ON
DO UNTIL ReadAD (AN0) <= LINEof
SET PORTC.1 OFF
SET PORTC.0 ON
LOOP
END IF
IF ReadAD (AN0) <= LINEof
SET PORTC.1 ON
SET PORTC.0 OFF
END IF
GOTO START
Just one more question, will it matter if I decide to wait a few seconds between each calibration and button press-- will the value of the variable keep changing... like:
WAIT UNTIL PORTC.2 ON
IF PORTC.2 ON THEN ReadingOne = ReadAD (AN0)
SET PORTC.4 OFF
WAIT 2 s
SET PORTC.4 ON
WAIT UNTIL PORTC.2 ON
IF PORTC.2 ON THEN ReadingTwo = ReadAD (AN0)
SET PORTC.4 OFF
WAIT 2 s
SET PORTC.4 ON
If I press the button, the variable value becomes the sensor reading. Now at this point the program flashes LEDs to tell me it worked so far... during that time if the sensor readings change does that mean the variable will keep on changing too?
i recommend using 3 sensors with the following algorithm pseudo code, i won the national titles with this(note this is pseudo code not gcbasic because i originally programmed in assember):
if left sensor detects line:
turn right until middle sensor detects it
if right sensor detects line:
turn left until middle sensor detects line
this way, if the motor is going fast and by the time the line is detected its already over the line, it will just turn until it is found! , theoretically, no matter how fast you are going, you should still catch the line.
ps: i suggest writing the calibration values to the onboard eeprom since this cant be reset to a pin value.
I have been doing experiments with a IR light sensor ( I bought a pack of IR emitter and IR detector from SparkFun for $2 part number SEN-00241)... That site has a link to basic circuitry for this IR detector.
I have been doing some experimentation with sensing light using this detector.
I have used the following code as a testbed for sensing and logging the data to the EEPROM in the chip (16F887). I then use the Read Chip feature in the MPLAB IDE to see the data stored in the EEPROM.
Hope this helps.
'Define Chip Model and its operating frequency in MHz
#chip 16F887, 4
'Define the Port Pin Assignments and my Descriptions
#define MaintStatus PORTD.1 'Pin function RD1 as the cpu signal to show with Green Steady LED when in maintenance mode
#define Activity PORTD.2 'Pin function RD2 as the cpu signal to show with Red Blinking LED of Activity
#define InActive PORTD.3 'Pin function RD3 as the cpu signal to show with Green Blinking LED if Inactive
'Analog PORT Definitions / Functions
#define PLightMeter PORTA.0 'Pin 2 (RA0/AN0) function AN0 as the sensor to detect the light level
'Define Analog Port Pin Functions
#define LightMeter AN0
'Other definitions
#define half_sec 50 10ms
'Set the Port Pin Directions
DIR MaintStatus OUT
DIR Activity OUT
DIR InActive OUT
DIR PLightMeter IN
'------------------- MAIN LOGIC -------------------
Main:
GOSUB set_ports
GOSUB lead_in_warning
GOSUB measure_light_level 1, 20
GOSUB lead_in_warning
GOSUB measure_light_level 21, 40
GOSUB lead_in_warning
GOSUB measure_light_level 41, 60
GOSUB completion_lights
END
'---------------------------------------------------
SUB set_ports
' Set OUT ports to OFF
SET MaintStatus OFF
SET Activity OFF
SET InActive OFF
END SUB
SUB lead_in_warning
'Indicate sampling is about to start
FOR Data_count = 1 TO 10
SET InActive ON 'Green
SET Activity ON 'Red
WAIT half_sec
SET InActive OFF 'Green
SET Activity OFF 'Red
WAIT half_sec
NEXT
END SUB
SUB measure_light_level (From_data, To_data) #NR
'Do twenty lightmeter readings
FOR Data_count = From_data TO To_data
SET Activity ON 'Red
WAIT half_sec
SET Activity OFF 'Red
'Do Measurement
Light_level = ReadAD(LightMeter)
EP_mem_addr = Data_count - 1 'eeprom addresses start at zero.
EPWrite(EP_mem_addr, Light_level)
NEXT
END SUB
SUB completion_lights
SET MaintStatus ON 'Green
SET InActive ON 'Green
END SUB