PDA

View Full Version : PIC16F84A using pulsout and TMR0



DragonBall_6
- 1st December 2006, 09:48
Hi All

I had so touble on the Pulsout and tmr0 interrupt.
Can I send a pulse in 4.32 second to the stepper motor driver (UCN5804B)and at the same time doing tmr0 interrupt to do the time and date.
For example: 8am start run the stepper motor in period=4.32second and 5pm the stepper motor back to its initial position.

Below are my code: Please give advice thanks you very very much
The code is ok i think ,but the period is NOT what I want.

' The program is doing the solar tracker using stepper motor 1.8degree(5V,1A)
' ANd it must be track in 15 degree per hour
' The clock using TMR0 is to activate the tracker to start and stop.
' I will also need to display the time on the LCD
'
' For Example: When 8 am the stepper motor start run in 15 degree per hour.
' gearbox 100:1 RATIO
'
' This code that I write just run in period 65.53 milisecond.
' The code is NOT what i need.

'WHAT I NEED IS TO SEND PULSE IN 4.32 second.
'BELOW PULSOUT 0,6553 WHICH IS ONLY 65.53MILISECOND.
' Code below can run but the pulsout time period is not what I want (period=4.32 second)

hour VAR BYTE
bm VAR BYTE
bs VAR BYTE
day VAR WORD
month VAR BYTE
year VAR WORD
s VAR BYTE
t VAR BYTE

hour=0:minute=0:second=0:

'TMR0 will interrupt every 65,536 milliseconds

OPTION_REG=%01010111 ' prescaler= 1:256
INTCON=%10100000

ON INTERRUPT GoTo start
TRISB=0 ' all port b set to output
High 1 ' stepper motor stop (Enable=high)
High 2 ' CW direction

'************************************************* ************************************
main:
PulsOut 0, 6553 ' clock pulse to the stepper motor driver UCN5804B
' 65.53 milisecond
GoTo main
************************************************** ************************************

' Interrupt service routine (ISR)

Disable ' Disable interrupts during interrupt handler
start : t = t + 1 ' Count pieces of seconds
IF t < 15 Then exit ' 15 ticks per second (65.536ms pertick)

'**********Time elasped = 1 second ***********
t = 0
bs = bs + 1
IF bs >= 60 Then
bs = 0
bm= bm + 1
IF bm >= 60 Then
bm = 0
hour = hour + 1
IF hour >= 24 Then
hour = 0

EndIF
EndIF
EndIF

exit: INTCON.2 = 0 ' Reset timer interrupt flag
Resume
End

HenrikOlsson
- 1st December 2006, 10:15
Hi,
I guess what you want is one pulse every 4.32s, in other words a frequency of 0.2315Hz.



'Produce squarewave on PortB.0 period~4.32s, 50% dutycycle.

Loop var Word

Main:
High PortB.0
For Loop = 0 to 2160 'Loop here for ~2.16s, tweak to match.
PauseUs 1000
Next
Low PortB.0
For Loop = 0 to 2160 'Loop here for ~2.16s, tweak to match.
PauseUs 1000
Next
Goto Main

Since the Pause statement in the For-Next loop is shorter (1mS) than what your interrupt period is (65mS) the ISR will still run.

However, your time-keeping will not be very accurate. You're only getting 983mS each second, give or take, 65536uS * 15 = 983040uS.

/Henrik Olsson.

mister_e
- 1st December 2006, 15:26
too bad PIC16F84a don't have 2 timers... The Henrik solution will work indeed, but i'll suggest to use shorter PAUSEUS, let's say 10uSec... OR a loop of @ nop.

If you need accuracy, you may decide to fine-tune it using MPLAB stopwatch OR measure it using an extra i/o and a scope.

Another solution... Use 2 variables, flags and 1 Timer.

There's many different ways.

DragonBall_6
- 2nd December 2006, 05:55
Hi all

Thanks to HenrikOlsson and mister_e that give me the marvelous advice.
I had tested it on the lab but the period is 4.6 and something 4.5. After I change it to For 0 To 2020 it will work 4.3 and something 4.2.
I just measure it using stopwatch.
For accuracy of the clock I will assign TMR0 = 12 {((fosc/4)*(256-12)*256)=0.9994}. Is that OK????

Mister_e has suggest me to use 10us pause. Which mean that the for loop have to increase to 216000 rite???
Sorry..I don't undestand the statement below:-

*****If you need accuracy, you may decide to fine-tune it using MPLAB stopwatch OR measure it using an extra i/o and a scope.
Another solution... Use 2 variables, flags and 1 Timer.*****************

HenrikOlsson
- 2nd December 2006, 13:07
Hi,
I don't follow you on the math....
If you reload TMR0 with 12 each interrupt you'll get (256-12) * 256 = 62464uS between each interrupt.

What kind of accuracy do you need? With the prescaler set to 1:256 and a TMR0 reload value of 178 you'll get (256-178)*256 = 19968uS between each interrupt plus a little for the time it takes to reload.

Another way would be to use an external xtal for TMR0, with a standard 32.768 watch xtal and the prescaler set to 1:128, you'll get one interrupt each second.

MPLAB have a simulator where you can run the code, it has a stopwatch function that can be used to "measure" how long a certain piece of code takes. I've never used it myself.

/Henrik Olsson.

mister_e
- 2nd December 2006, 19:39
Instead of using StopWatch, you may measure it in real-world. Use a scope and measure the time using an extra I/O.

Example:

High AextraIO
' code you need to evaluate
LOW AextraIO

You place your scope (or frequency meter, etc etc) on the AextraIO pin and you measure it.

something handy for your Timer Calc
http://mister-e.org/pages/utilitiespag.html

DragonBall_6
- 3rd December 2006, 11:04
Thanks to the advice and reply, I really appreciated it.

From the interupt I know that I could add in the date.Such as day=day+1,month=month+1 and so on....

I have another matter which is WHERE can i store 365 sunrsie time?
My algoritm is just like that:-
1 jan 2006 the sunrise time is 6:10 motor start run and 2 jan 2006 the sunrise time is 6:15 and so on.

I know that it is impossible for me to store 365 data in the PIC16F84A eeprom.
Can I store my data into the program memory or RAM?????

Please advice and thanks you very much...

mister_e
- 3rd December 2006, 20:19
you could save it to the codespace and play around the following
http://www.pbpgroup.com/modules/wfsection/article.php?articleid=10

or, use an external EEPROM.

DragonBall_6
- 4th December 2006, 10:36
Hi all
Thanks for the reply.

Just now on the lab I have try to display the word in the LCD but NOT SUCCESS.
Below is the code I follow all the connection on the PBP manual using PIC16F84A. LCD is bought from the www.cct.com.my.


‘ Set LCD Data port
DEFINE LCD_DREG PORTA
‘ Set starting Data bit (0 or 4) if 4-bit bus
DEFINE LCD_DBIT 0
‘ Set LCD Register Select port
DEFINE LCD_RSREG PORTA
‘ Set LCD Register Select bit
DEFINE LCD_RSBIT 4
‘ Set LCD Enable port
DEFINE LCD_EREG PORTB
‘ Set LCD Enable bit
DEFINE LCD_EBIT 3
‘ Set LCD bus size (4 or 8 bits)
DEFINE LCD_BITS 4
‘ Set number of lines on LCD
DEFINE LCD_LINES 2
‘ Set command delay time in us
DEFINE LCD_COMMANDUS 2000
‘ Set data delay time in us

Pause 100 ' Wait for LCD to startup
LCDOut $fe, 1 ' Clear LCD screen
LCDOut "Hello" ' Display Hello

End

Please advice and thanks

HenrikOlsson
- 4th December 2006, 11:10
Hi,
Double check all connections. Do you have the pullup resistor on RA4?

/Henrik Olsson.

mister_e
- 4th December 2006, 21:33
AND never finsih your program with a single END... use a endless loop or PBP STOP.


LCDOUT $FE,1,"Your stuff"
Loop:
Goto Loop

DragonBall_6
- 5th December 2006, 01:11
Hi all,
Thanks for the reply.

Regarding the LCD everyting look fine in my circuit. After power on the, the LCD come 16 small black square on the screen but it does not display "Hello".

Regarding the website that u given to me i'm not very understand. Do you have the simple one and is in the pure PicBasic Pro language. Besides in the website I noticed one things which we can add 2 or more interrupt at the same time..But I go thru this I not really understand.....Thanks

Below is the statement that provide by the mister_e:-

****************too bad PIC16F84a don't have 2 timers... *********
************************************************** ******
I'm planned to use the PIC16F876A there got timer 0 ,1 and 2.

(1) Is that possible using 2 interrupt in a single program.??

(i) One interrupt (tmr0) is for the clock pulse to send to the stepper motor driver
(ii) One interrpt(tmr1) is for the 1 second elapsed.

If the above possible...Does it mean that in the program I need to have two
ON INTERRUPT code..

Please guide me thru this..... Thanks you all very very much........

HenrikOlsson
- 5th December 2006, 06:39
Hi,
Basicly you can have as many interrupts sources as the PIC has (TMR0, TMR1, USART, RB0, RBChange, CMP, ADC, whatever.....). When the program interrupts and starts executing the ISR (InterruptServiceRoutine) you need to check what caused the interrupt and act uppon it accordingly.

My approach to this would be to use an external 32.768kHz xtal, set the TMR of your choise up to generate an interrupt at 100Hz, then in the ISR count those ticks. When you have 100 ticks you have a second. When you have 216 ticks, toggle your step pin.



Ticks var byte '1/100th seconds
StepTicks Var Byte '1/100th seconds, used for step pulse timing
Seconds var Byte 'Seconds
Minutes Var Byte 'Minutes
Hours var Byte 'Hours
Days var Byte 'Days, perhaps change this to a Word.

Goto Main 'Jump over ISR.

DISABLE

ISR:
'Reload timer with correct value here, and restart it.

Ticks = Ticks + 1
If Ticks = 100 then
Ticks = 0
Seconds = Seconds + 1
If Seconds = 60 then
Seconds = 0
Minutes = Minutes + 1
If Minutes = 60 then
Minutes = 0
Hours = Hours + 1
If Hours = 24 Then
Hours = 0
Days = Days + 1
Endif
Endif
Endif
Endif

StepTicks = StepTicks + 1
If StepTicks = 216 then '2.16s, time to toggle the step pin.
StepTicks = 0
Toggle StepPin
Endif

RESUME
ENABLE

Main:

'---------------------------------------------
'Your main code here.......
'remember, NO time consuming commands, like Pause, sleep, nap etc.
'----------------------------------------------
Goto Main


This is completely untested and just something to show you one approach. Also, I suggest you'll have a look at Darrel Taylors Instant Interrupts, search the forum, it makes interrupts a breeze but MAY be overkill in this application.

About that LCD, if your connections ARE fine and matches your DEFINES then the only thing I can think of is a longer pause at the beginning OR you could try to increase the command and data delay with:


DEFINE LCD_COMMANDUS 2000 '<-----Increase this...
DEFINE LCD_DATAUS 50 '<----and this.


/Henrik Olsson.

DragonBall_6
- 7th December 2006, 13:33
Hi all

One question to ask...

I actually want to display "Time: 00:00:00"
The LCD is working but the problem is it is only happen when i use crystal 2.4576Mhz.

When i change my crystal to 4Mhz it will just display "00:00:00"
without seeing the word "Time"..
I had add the pull up esistor to 1k ohm and DEFINE LCD_COMMANDUS 1000. Is that ok???

Why??
Does it need to pause more longer???


Thanks

HenrikOlsson
- 8th December 2006, 06:27
Hi,
Do you have DEFINE LCD_COMMANDUS 1000 in your code? If that's the case try increasing that to 2000 to start with. If that doesn't help put a PAUSE 500 right at the beginning of the program, that will let the LCD startup for sure.

If that doesn't help either, increase the COMMANDUS and DATAUS defines. Test with 10000 for COMMANDUS and 500 for DATAUS just to see if it helps. If it works, try to find the sweetspot just over where it stops working.

/Henrik Olsson.

skimask
- 8th December 2006, 13:32
Hi,
Do you have DEFINE LCD_COMMANDUS 1000 in your code? If that's the case try increasing that to 2000 to start with. If that doesn't help put a PAUSE 500 right at the beginning of the program, that will let the LCD startup for sure.

If that doesn't help either, increase the COMMANDUS and DATAUS defines. Test with 10000 for COMMANDUS and 500 for DATAUS just to see if it helps. If it works, try to find the sweetspot just over where it stops working.

/Henrik Olsson.


Unless PBP has been fixed, I seem to remember that the DATAUS define was actually a byte define. In other words, if you specify DATAUS 257, it'll actually come out to be DATAUS 1. I could be wrong. The COMMANDUS is still a word define. I'll check a .lst file when I get home tonight to confirm that.
JDG

HenrikOlsson
- 8th December 2006, 15:06
Hi Skimask,
Thank you! I didn't know about that. Please let us know what you find out!

/Henrik Olsson.

skimask
- 9th December 2006, 09:17
Hi Skimask,
Thank you! I didn't know about that. Please let us know what you find out!

/Henrik Olsson.



I just checked it out.
If you look in any .lst file that contains any LCD defines or usage, you'll see that the LCD_COMMANDUS is a word variable internal to PBP and, as I suspected, LCD_DATAUS is a byte variable internal to PBP. So, you can't use anything higher than 255 in LCD_DATAUS.
Another thing to be changed in upcoming PBP manuals...
JDG

mister_e
- 9th December 2006, 10:38
well, i've NEVER use a higher value than 100uSec (50uSev typical) on those various LCD i work and i worked. I don't believe there's some on the market that will really need more than 100 uSec.

If the LCD show only Black square it's because it fail to initialise properly or the contrast is set to max.

Reasons to fail:
Too short startup delay, some may need up to secondes... try PAUSE 2000, if it works, reduce it 'till you find a comfort zone
Some wires are swapped between them
In 4 bit mode, you must use DB4, db5, db6,db7.... AND some model need to send unused pins somewhere gnd or VDD, check the datasheet
the R/W is not connected to GND
you're using RA.4 without pull-up resistors
your supply line is poor and noisy
you're using a xtal>4 MHZ and you didn't set HS config fuse

HenrikOlsson
- 9th December 2006, 14:59
Hi,
Thanks for verifying that Skimask!

Steve, you are most certanly right about the timing, no LCD should need more than 100uS for data. But my advice of trying with 500 was not a very good one since I didn't know of the 8-bit clamp.

All valid points from you Steve, Dragonballs problem seems to be timing related since it works when he's using a slower clock than 4Mhz. But at 4Mhz it seems to skip the first characters, if I understood it correctly.

/Henrik Olsson.

skimask
- 9th December 2006, 19:46
Hi,
Thanks for verifying that Skimask!

Steve, you are most certanly right about the timing, no LCD should need more than 100uS for data. But my advice of trying with 500 was not a very good one since I didn't know of the 8-bit clamp.

All valid points from you Steve, Dragonballs problem seems to be timing related since it works when he's using a slower clock than 4Mhz. But at 4Mhz it seems to skip the first characters, if I understood it correctly.

/Henrik Olsson.



I think the 500 idea was good enough since 500-256=244. Should be more than enough for a data delay...
Put a 5 second pause at the beginning of the program, that'll extinguish any doubt about the power up on the LCD. If that don't fix it, it's something else.
JDG

Archangel
- 10th December 2006, 07:29
Hi DragonBall_6,
As I didn't see it listed in your code, do you have appropriate define osc X in your code and question 2 is have you set config fuses to HS when trying to use fast oscillator speed?
JS

DragonBall_6
- 12th December 2006, 08:57
Thanks to all the reply,

After I change it to PIC16F876 and 4Mhz cystal, pause 500, commandus 2000 and dataus 1000. It is work.
I had adding 4 button to increment the hrs,minute,day and month.
I feel happy.THANK YOU ALL THAT PROVIDE ME A LOT OF INFORMATION.

I have thinking to advancing my project by using the A/D function.
The idea is get the input from the solar PV and sent into the PIC16F876.
When the voltage is lower than 2 volt then motor stop and vice versa.
The input voltage from the solar PV is up to 15 volt.

Can someone help and guide me thru the basic part such as the initialization of the of the PIC???
Possible that the PIC get the analog input above 5Volt????

Any suggestion and Please advice....Thanks

HenrikOlsson
- 12th December 2006, 11:19
Hi,
If you look at the ADCIN command in the PBP manual you'll see how it's done in its simplest form. Basicly you set the pin you want to use to be an input via the corresponding TRIS register then you set the pin to analog via the ADCON1 register. Look up the ADCON1 register in the datasheet.

Use a simple voltage divider between the solar PV (?) and the PIC pin. Take two resistors, one 2.2k and one 1k. Connect them in series across the 0-15V voltage with the 1k closest to ground. Connect the PIC pin to the junction between the two resistors. Don't forget that the ground from the solar PV must connected to the PICs ground. This will produce a voltage of 0 to 4.68V on the PIC pin for 0-15V from the solar PV. It will draw ~4.7mA from the solar PV.

So....


DEFINE ADC_BITS 10 'Set ADC to produce 10bits
DEFINE ADC_CLOCK 3 'Set ADC clock to internal RC
DEFINE ADC_SAMPLEUS 50 'Set conversion time to 50uS

TRISA.0 = 1 'Set RA0 (pin2) to input.
ADCON1 = %10001110 'Set RA0 to analog, internal Vref, result right justified. (See datasheet)

SolarVoltage var WORD 'Store AD conversion result here.

Loop:
ADCIN 0, SolarVoltage 'Read AN0, store result in SolarVoltage.
LCDOUT $FE, 1, #SolarVoltage 'Display value on LCD
Pause 500
Goto Loop

If you use the resistor values above the reading should vary somwhere around 0 - 958 give or take. (For a 0-15V input)

/Henrik Olsson.

DragonBall_6
- 13th December 2006, 00:38
Thanks to the reply.
Solar PV also called photovoltaic cell (direct absord sunlight and generate electricity).

***LCDOUT $fe,$1, #solarvoltage*****

Thus, the LCD only can display the value not above 5 volt,am I right??
If this is the case, if I want to display value above 5v on the LCD then is that possible.

If I'm using 4 Mhz crystal, do I need to have this sentences ***DEFINE ADC_CLOCK 3****?????


Thanks and please advice.

Archangel
- 13th December 2006, 01:21
Thanks to the reply.


Thus, the LCD only can display the value not above 5 volt,am I right??
If this is the case, if I want to display value above 5v on the LCD then is that possible.

.
Hi DragonBall_6,
What the voltage divider does is input voltage based upon the resistors ratio into the pic pin and hopefully limit it's input voltage to TTL levels. You have to write the code to do the math and then output the voltage numbers to suit your purpose. If you store the ADC value in a byte variable then ( and I am going out on a limb here as I am as new to pic programming as you are ) you should be able to express that as a number from 0 to 255. So if 5 v = 255 (input pin at 5 v when solar panel is at 15 volts) then 255 = 15 volts.So with a given voltage divider you can express 15 volts incremented in 255 steps. Anyone out there who is more knowledgable please ring in!
JS

HenrikOlsson
- 13th December 2006, 06:13
Hi,
Just as Joe says, the two resistors forms a voltage divider that "divides" the voltage fed to it by the ratio between the two resistors. The upper one is 2.2 times larger than the lower one so will loose 2.2 times as many volts over that one than over the lower one. Or if you wish to put ohms law to the test:

The total resistance is 3.2k, with a voltage of 15V there will be a current of (I = U / R) 4.6875mA flowing thru the two resistors. Now that current will produce a voltage over the lower resistor of (U = I*R) 4.6875V.

Since the PIC's AD pin is connected in parallel with the lower resistor the PIC will "see" a voltage between 0 and 4.6875V when the voltage from the solar PV is between 0 and 15V.

Now, in the code I showed you we set the ADCON1 register in a way that the ADC uses the PIC's powersupply as a reference voltage. What that means is that whatever the powersupply voltage is at the moment will produce the max reading from the ADC, so for the above to work it's important that the powersupply is stable at 5.0V.

We also said


DEFINE ADC_BITS 10

What that does is set the ADC code to give you a resolution of 10bits, or put another way, the result from the ADC will be between 0 - 1023. That is 0V on the input will give you 0 in SolarVoltage and 5V in will give you 1023 in SolarVoltage. The display will show that value, not the voltage.

To get the display to show actuall volts you need to scale the value. With a powersupply of 5.0V each bit in the ADC result is 0.00488V (5/1024) so if the display shows 958 the voltage at the PIC pin is ~4.67V which in turn corresponds to ~15V from the solar PV. (See the voltage divider)

Are you going to display the "real" voltage or just using the value to decide when to start the motor? If the later then you don't need to scale it at all, just use it as it is.

The DEFINE ADC_CLOCK 3 tells the ADC module inside the PIC what clock source to use. It has nothing to do with the Xtal you are using to drive the PIC.

/Henrik Olsson.

mister_e
- 13th December 2006, 06:27
and '3' comes from the datasheet in the ADCON1 register setting (register 11-2, page 128) ADCS2 table

DragonBall_6
- 14th December 2006, 00:19
Thanks to all the reply.
I really appreciated it. I will try it at lab.
Actually, I would like to receive A/D input from solar PV and after that there are 2 things to be done.
First, IF the A/D input is less that 2 volt then stop the motor ELSE the motor activated.
Secondly, at the same time A/D input from the solar pv is sent to the computer for processing and collected the data for every 15 minute. The result will be calculated and show in graph.
It would need some knowledge of the visual basic as database and link between vb and ms excel.

Somebody can guide me thru this?? Thank and please give advice.

HenrikOlsson
- 14th December 2006, 05:44
Hi,
Just compare the value you get from the ADC with the value that corresponds to 2V, if higher then run the motor, if lower then stop it, you can figure that out. You may need to introduce some hysteresis around the threshold.

Then send the value to the PC using the PBP's SEROUT command, or even better use the USART, a MAX232 level shifter and the HSEROUT command, see the manual. There's many examples on the forum.

For the PC/VB side have a look here: http://www.rentron.com/VisualBasic.htm
Just send the raw value from the PIC and use VB to scale it to volts if you like.

/Henrik Olsson.

DragonBall_6
- 14th December 2006, 06:35
I had try the program that you gave me. It is work.Thank.
Some problem has finding out....



***********'Produce squarewave on PortB.0 period~4.32s, 50% dutycycle.

Loop var Word

Main:
High PortB.0
For Loop = 0 to 2160 'Loop here for ~2.16s, tweak to match.
PauseUs 1000
Next
Low PortB.0
For Loop = 0 to 2160 'Loop here for ~2.16s, tweak to match.
PauseUs 1000
Next
Goto Main**********

The above is the code that you posted to me. Thanks to you again.
I had modify it like the code below:-

********'Produce squarewave on PortB.0 period~4.32s, 50% dutycycle.

Loop var Word
SolarVoltage var word
ADCON1 = %10001110

Main:

High PortB.0
For Loop = 0 to 2160 'Loop here for ~2.16s, tweak to match.
PauseUs 1000
ADCIN 0,SolarVoltage
LCDOUT $FE,$1,#SolarVoltage
If SolarVoltage = 300 then
high motor ' motor stop
ELSE
low motor ' motor run
ENDIF
If update = 1 then
LCDOUT $FE,$C0,DEC2 Hour,":",DEC2 Minute,":",DEC2 Second
ENDIF
Next
Low PortB.0
For Loop = 0 to 2160 'Loop here for ~2.16s, tweak to match.
PauseUs 1000
ADCIN 0,SolarVoltage
LCDOUT $FE,$1,#SolarVoltage
If SolarVoltage = 300 then
high motor ' motor stop
ELSE
low motor ' motor run
ENDIF

If update = 1 then
LCDOUT $FE,$C0,DEC2 Hour,":",DEC2 Minute,":",DEC2 Second
ENDIF
Next
Goto Main

ON INTERRUPT
'
'Time calculation
'
'
Update = 1 'update diaplay after 1 second*************


The display: ****************
0 ' when increase the A/D input, the value
00:00:00 'increase to 0 then 1 then 2 then
**************** 'maximum is 3

HenrikOlsson
- 14th December 2006, 08:54
Hi,
Yes, you are correct, that will never work.

A couple of things.

1) The timing to produce the pulses to the motor is depending on the For Next loop and the PauseUS. When you insert a whole lot of other commands in there the timing will be WAY off. For example, the ADCIN alone will take at least 50uS, remember the DEFINE ADC_SAMPLEUS 50 then comes the LCDOUT which will take a "lot" of time also.

Do you need the LCD to update 1000 times / second? That is what it's trying to do since you put it inside the FOR-NEXT loop.

2) It is the For Next loop that pulses the step line to the motor. What are you trying to do with the high motor, low motor? Do you have an enable signal to the motordriver that is mapped to motor

3) There's code missing in the INTERRUPT routine and the ON INTERRUPT statement should be at the beggining of the program with a LABEL telling it where to jump when an interrupt occurs.

4) The ADC DEFINES are missing.

5) The TRIS register set-up are missing.

6) The motor variable(??) declaration is missing.

7) You are checking if the SolarVoltage varible is equal to 300, so even if all the rest where OK the motor would only run when the value was exacly 300. You need to check if it's higher than 300.


This is probably not the best way to this now that you are adding more and more stuff to it but it may get you going if you have decided to go this route instead of the interrupt and tick counting we also showed you.

Again, this is completely untested! You will probably need to tweak the 2160 value in the For Next loop a little bit to get the correct timing.


Loop var Word 'Loop variable for the FOR-NEXT loop
SolarVoltage var word 'Raw value from ADC
RunMotor var bit 'Enable bit for step pulse routine.

DEFINE ADC_BITS 10 'Set ADC to produce 10bits
DEFINE ADC_CLOCK 3 'Set ADC clock to internal RC
DEFINE ADC_SAMPLEUS 50 'Set conversion time to 50uS

TRISA.0 = 1 'Set RA0 (pin2) to input.
TRISB.0 = 0 'Set RB0 as output, step pulse to motor.
ADCON1 = %10001110 'Set RA0 to analog, internal Vref, result right justified. (See datasheet)

RunMotor = 0 'Do NOT run motor

Main:
'//The IF statement here checks the flag to determine if the motor should be run or not.
'// If it should be run the For-Next loop is executed.
If RunMotor = 1 then 'Produce pulses ONLY if supposed to....
High PortB.0
For Loop = 0 to 2160 'Loop here for ~2.16s, tweak to match.
PauseUs 1000
Next
Low PortB.0
For Loop = 0 to 2160 'Loop here for ~2.16s, tweak to match.
PauseUs 1000
Next
Endif

ADCIN 0, SolarVoltage 'Get value from solarPV
LCDOUT $FE,$1,#SolarVoltage 'Display value on LCD

'// Here you can insert the code for sending to PC //
'// and the LCD code for the time, if that's what your doing //

If SolarVoltage > 300 then 'We are over the thershold
RunMotor = 1 'so lets enable the step pulses
Goto Main 'and start over
Else
RunMotor = 0 'disable the ste pulses.

'// Since the For-next loop that produces the step pulses is not running now we insert a pause here.
'// Otherwise the ADCIN and LCDOUT statements will execute VERY often.
For Loop = 1 to 1000
PauseUs 1000
Next

Goto Main


When you post code please include comments so that it's easier for us to understnad what you're trying to do. Also, please see the vbCode page here: http://www.picbasic.co.uk/forum/misc.php?do=bbcode for how to post code so that it shows in a window like above.

/Henrik Olsson.

DragonBall_6
- 27th December 2006, 16:58
If I doesnt want to use external eeprom and I had used up all the internal eeprom space. As I know there was a way to store the data in the program like below:-

asm:
da:1,2,23
endasm

I do not familiar with this could any one one lead me thru this method? Thank
I just want to store 200 data in there.

Thanks