Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

The best way to free up some time on a pic 18F

Status
Not open for further replies.

be80be

Well-Known Member
I was thinking I could open up some time to run my main loop using a 555 timer set to give a 1 second tick that dec my counter.
What do you think?

Time I keep up with PORTB changes the counter I'm using works fine but my switch test code lags behind.

So I figure the 555 would give a full second almost.

Any pro's or con's here on this I don't need a 100% timer here if it's slow people will be happier.
 
How accurate does your timing need to be? The usual 555 timing circuits are subject to drift through temperature change, capacitor leakage etc.
 
Can you use the timer interupt to generate the 1 second ticks?
That way to processor is free to do what you require of it while the counters are counting up (down?) to the next 1 second tick.

JimB
 
I have a bunch of switches and a DS18b20 to read and I set timer0 to Interrupt at 1 sec but my switch code and the math to do the LCD and the DS18b20 I don't get updated fast enough.

So I figure I'd try the 555 but now that I think about it a 10f200 would fit the bill better. See im counting down 7 minutes based on how many coins are dropped in the coin counter. As long they get 7 to 8 minutes a coin every one well be happy.
 
I have a bunch of switches and a DS18b20 to read and I set timer0 to Interrupt at 1 sec but my switch code and the math to do the LCD and the DS18b20 I don't get updated fast enough.

Hey Burt, is this a BASIC program and could I take a look at it, please?
 
This is the timer code
Code:
Device = 18F2520      // Tells whitch  chip im using
Clock =8             // tell the complier to base on a 8 Mhz clock for delays.
Config OSC = INTIO67   // sets OSC it onboard  oscillator
#option LCD_DATA = PORTC.4
#option LCD_RS = PORTB.0
#option LCD_EN = PORTB.1

Include "intio8.bas"   // set's the osscon to 8 Mhz
Include "LCD.bas" 
Include "utils.bas"
Include "convert.bas"
Include"timer0" 
Dim ds As Word
Dim min As Word
Dim sec As Word
Dim LED As PORTB.4
Event drytime()
    sec = sec -1
    min = min -1
    If sec = 0 Then
        sec = 59  
     EndIf
End Event 

Interrupt ISR() 
     If Timer0.InterruptFlag =1 Then 
        Timer0.SInterrupt() 
     EndIf 
End Interrupt  
SetAllDigital() 
Output(LED)
Timer0.Initialize(drytime) 
Timer0.SetPrescaler(Timer0.PS256) 
Timer0.EightBit = 0 
Timer0.Preload = 55000 
Timer0.LoadCount(Timer0.Preload)      // **ADDED** to load count 
Timer0.EnableInterrupt() 
Timer0.Enabled() 
Enable(ISR)
min = 420
sec = 59 
While true
      ds = min / 60    // to get the minutes
    LCD.WriteAt (2,1, "time:" ,DecToStr(ds),":", DecToStr(sec))
If min = 0 Then    // timed out
     Toggle (LED)   // led toggle
     min = 420
EndIf
Wend

But it's close to the 7 minutes count down I'm redoing the switch code to use Interrupt on change.
This was my first go at the switch code but when I added the timer0 event code it lag's the main loop.
Code:
Dim lowS As PORTA.0
Dim medS As PORTA.1
Dim hiS As PORTA.2 
Dim coin As PORTA.3
Dim led1 As PORTB.2
Dim led2 As PORTB.3
Dim led3 As PORTB.4
Dim X As LongWord
Dim T As LongWord
Dim ds As LongWord 

Sub setHeat()
If lowS = 0 Then 
        DelayMS(20)
    EndIf 
    If lowS = 0 Then 
        High (led1)
        Low (led2)
        Low (led3)
    EndIf
    
    If medS = 0 Then 
        DelayMS(20)
    EndIf 
    If medS = 0 Then 
        High (led2)
        Low (led1)
        Low (led3)
    EndIf
    
    If hiS = 0 Then 
        DelayMS(20)
    EndIf 
    If hiS = 0 Then 
        High (led3)
        Low (led1)
        Low (led2)
    EndIf
End Sub
Output (led1)
Output (led2)
Output (led3)
Input (lowS)
Input (medS)
Input (hiS)
Input (coin)                     
 ADCON1 = $0F
 CMCON = $07
SetAllDigital
  X = 0
  T= 0
 // mS = 0 // Reset the mS counter
  //TMR0_Event = False // Clear the TMR0 Event Flag
  //TMR0_Initialize // Setup and enable TMR0
While true 
    If coin = 0 Then 
        DelayMS(100)
    EndIf
    If coin = 0 Then
        X = X +25 
    EndIf
    LCD.MoveCursor (1,1)
    LCD.Write (DecToStr(X))

    If X <> 0 Then
        setHeat
    EndIf
    If led1 = 1 Then 
        LCD.MoveCursor (2,1)
        LCD.Write ("Low ")
    EndIf
    If led2 = 1 Then 
        LCD.MoveCursor (2,1)
        LCD.Write ("Med ")
    EndIf 
    If led3 = 1 Then
        LCD.MoveCursor (2,1)
        LCD.Write ("High")
    EndIf 
   // T = ds
    //LCD.MoveCursor (2,8)
   // LCD.Write (DecToStr(T))

    
Wend

I'm working each part out in blocks that will be modules that are called in the main
the DS18b20 code is not in here now because I may use the old heat sensor after testing them there not to hard to use.
Here the basic board layout pins not marked on the pic still working on the idea of what chip the 18F2520 cost as much as two 18fxJx chips and they have rtc that would make it easy to count minutes

**broken link removed**

I wrote code that let me manually test a broad that I made on strip board it works great that is the hardware works great counts the coins right sets heat and stuff right but with the timer it can miss a coin and can't have that.
 
Last edited:
Mike's asked you about the code so I'll leave that, but here are a couple of generalisations;

You are using a 18F2520 at 8MHz clock, if you could free up 2 PIC pins for a xtal osc you can use 32MHz HSPLL mode (or 40MHz HSPLL mode) which is 4-5 times faster. In a pinch you can run the 3 LEDs on the LCD data lines, this is done all the time even in commercial devices.

If you changed the temp sensor to a LM35 it has similar accuracy to the DS sensor but it has a analogue output so you can read the temp value instantly with an ADC pin by reading the ADRES register, this saves a ton of time doing 1 wire comms to the DS sensor, which is essentially wasted time.

The MikroBASIC LCD functions LCD.Movecursor and LCD.Write are very slow compared to writing your own. You can still use the MikroB init function, and the move and write functions are quite simple to code up. You can make all the LCD writing 3-4 times faster than the compiler library functions.

(edit) Also, your schematic for the DS sensor is wrong, it shows the signal wire shorted to the Vdd wire. ;)
 
Last edited:
The '2520 can run the INTOSC with 4xPLL for 32 MHz so you don't really need a crystal...

Burt, the pull-up on the DS18B20 is not wired correctly.

I'm taking a closer look at the Swordfish BASIC modules you're using. I think you should be able to build a program structure that provides the responsiveness you're looking for.

What about the original temperature sensor? Do you know how it works and how to interface to it?
 
Last edited:
It's hooked up right just not showed right the pullup is on the plug on the DS18B20 I drawled it wrong LOL I fixed the drawing to show it right. Thanks for pointing that out it's soldered from Vdd to the data pin I wasn't going to even show that but I did and and I did it wrong. It's a NTC Thermistor 100K

Im hooking her up like this I tested them last night.
View attachment 69197

The old board has them hooked like that using a ADC 0831 8-bit A/D converter and 8048 cpu And it had has a 555 set for a 1 sec tick
 
Last edited:
Is there anything special about the coin sensor, Burt? Does it send out a stream of pulses or just a single pulse when it accepts a coin? Instead of treating it as an 'event' in real time, can it be sampled like a regular push button switch at 20 or 25 msec debounce intervals?
 
Generally what i do is avoid FP math, isolate any time consuming BASIC code and write an asm module to do it, use interrupts to handle time critical aspects like 7 segment display updates. Reduce the frequency of ADC sampling due to the wait states required and use flags to limit use of subroutines until they are required, rather than have them always execute in the main loop.

What is interesting is that folks who start off with the higher performance chips tend to ignore efficient code planning and depend on the chips 'power' so to speak. I am a bit of a minimalist when it come to chip speed.

BTW you can have the PIC alter it's processing speed on the fly depending on the model. So 'crunching' thru a processor intensive bit of code can be handled by 'clocking up' and then 'clocking down' after. This is useful for power conservation, but u need to know that interrupt timer based ticks can accumulate errors if absolute long term timing accuracy is desired.
 
Which is how I structure my software, but it took a while to get the experience to get away with it, the delay in my lcd driver is interrupt driven and the processor is free while the delay is 'delaying', but it took a lot of coffee and screen staring to get it to work well.

Burt, can you write subs in asm and call them from the main basic program?, might be a good way of getting some more time.
 
Last edited:
I had a simular (but different) application for starting a motor not more than 3 times per 10min. Every start subtracts from available energy count. After reading about your application i change the code to cater for a coin-operated device. A counter is reset to its current output value plus the value assigned to a coin every time a coin is detected. This counter is downcounting per second if the machine is running. A second code section handles the machine on/off. You can only switch on when there is a count and no interlock present, and it will switch off when count reach 0 or interlock present. A 3rd section will decode the remaining time (in seconds) into hour,minute and seconds values for display. The 3 code sections was implemented using a function block approach (see thread on Function Block IDE). Total time to execute was 747 cycles which translates to less than 100uSec. So as you can see i had no problem with time.
NOTE: wanted to include a screenshot of the code but for some reason could not.
 
This is my problem I never really used interrupts much I always tried to write code that didn't need them but this thing has to read when a coin is dropped and the display is 4 digit seven segment which the module for swordfish pops a interrupt really fast so you end up missing the coin drop. But I figured a way to handle this I made a serial display to take the load off the main uC.

It's all coming together now one block at time A friend of mine has 14 older dryers that are in fine shape but the old main board used a cpu which handle these tasks easy. But there hard to find a replacement for these so I figured I'll give it a go made two boards on pref board tested one out on Saturday it worked great i was sending the display data to my laptop but I have the display working now.

 
Last edited by a moderator:
Put the coin input on an interrupt pin (RB0) but don't enable the interrupt. When a coin is entered RB1IF will get set but no interrupt will be generated. Alternatively, use Timer0 to count the coins. Whenever it changes value a coin was entered.

Mike.
 
Last edited:
I like the Timer0 doing the counting. No worries with what the MCu is up to when a coin drop pulse rolls in. It's just a matter of optimizing which peripheral mix you use to suit your priorities.
 
Mike I like your idea but how do I deal with the 40mS of switch bounce I've never used a timer to handle debounce. Mosaic that's a ideal too thanks both of you but could you maybe show a simple code showing how to deal with the bounce can't give them a hour for a quarter
LOL.

Here a video of the counter.
[video=youtube_share;N3IapAJrk9I]http://youtu.be/N3IapAJrk9I[/video]
 
Mike are you saying that RB.0 will set a flag RB1IF ? like 0 no change 1 you dropped a quarter that I just reset and add a coin to the coin counter.
 
So your the guy to blame when I put coins in the local bagwash and they dont register.

As mentioned if you used timer 1 you could count coint coins in hardware, you'd need an rc to debounce the i/p, probably better though in your case to use 2 processors, if you ever need to change anything you'll have the means to do it, rather than an over stretched chip doing it all.

Another way in hardware would be to use a nand flip flop and a changeover microswitch to debounce the i/p, then connect that to something like a 4040 so you can count independantly the no. of coins, just reset the 4040 in software when its read.
 
Last edited:
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top