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.

need a 4 minute delay

MrDEB

Well-Known Member
I have Time_delay declared as a LONGWORD
[ICODE
//TURN ON THE RED LED STRIPS (100 ON TOP OF CAKE)
Red_Candle_STRIPS = 1 //turn on the red 100 on top of cake
time_delay = time_delay + 1
until
time_delay = 240000 // 4 miniutes

][/ICODE]
Not sure if this is a good method to have other code running until Time_delay = 240000
 
Generally speaking, timing loops are not a good way to go. You don't mention the microcontroller but pretty much all have timers that can generate a periodic interrupt. Set the timer to interrupt every, say once per second. Put the time_delay = time_delay +1 part in the interrupt service routine. Then your foreground code can check to see if time_delay has reached 240.

Something to watch for. If your time_delay variable is wider than the microcontrollers native word width. Say your variable is 16 bits but you are on an 8-bit micorcontroller. You need to disable the timer interrupt when you check the time_delay. Otherwise, the timer could change between the foreground access of the first byte and the foreground access of the second byte.


If you are really only going to have the one timer, then it is often better to make it count down. Replace
time_delay = time_delay + 1
with
if (time_delay) time_delay = time_delay - 1;

Now you set the timer by giving it the delay value, such as
disable_interrupts()
time_delay = 240
enable_interrupts()
and you know the timer has expired whtn time_delay becomes zero

You can also avoid the interrupt problem by adding a timer expired flag that can be accessed atomically. Like it's just one byte. Then the ISR does
if (time_delay) time_delay = time_delay - 1; else flag=1;
Now you set the timer with
flag = 0;
time_delay = 240;
then you just watch flag and when it becomes non-zero, you know 4 minutes have elapsed.
 

danadak

Well-Known Member
Most Helpful Member
Remember in interrupt routines any variable declared outside it
and used in the routine must be declared volatile.




Regards, Dana.
 

MrDEB

Well-Known Member
this is an 8 bit 18f2221 pic
only need one timer
here my present code it is in Swordfish basic
Code:
{
*****************************************************************************
*  Name    : UNTITLED.BAS                                                   *
*  Author  : [select VIEW...EDITOR OPTIONS]                                 *
*  Notice  : Copyright (c) 2022 [select VIEW...EDITOR OPTIONS]              *
*          : All Rights Reserved                                            *
*  Date    : 11/26/2022                                                     *
*  Version : 1.0                                                            *
*  Notes   :                                                                *
*          :                                                                *
*****************************************************************************
}
Device = 18F2221
Clock = 8
#option DIGITALIO_INIT = true     // tell compiler to automatically call SetAllDigital
Include "setdigitalio.bas"
Include "intosc.bas"   
#option SWORDFISH_SE = true
'Include "setdigitalio.bas"//Include "SetDigitalIO.bas"
Include "utils.bas"
Include "Convert.bas"

Dim Time_delay As longword
Dim X As Byte
//12 VOLT LED STRIPS
Dim R As PORTA.0
Dim Y As PORTA.1
Dim D As PORTA.2
Dim E As PORTA.3
Dim R_1 As PORTA.4
Dim W As PORTA.5
Dim O As PORTA.6
Dim D_1 As PORTA.7
Dim Red_Candle_STRIPS As PORTB.0  //turn on mosfet Q10
Dim Flames As PORTB.1  //TOGGLE SWITCH PORT

//CAKE SPRINKLES CATHODES USING MOSFETS    mosfets ar? cycle through the COLUM (SPRINKLES)  not the  ROWS
Dim Row_4 As PORTB.2
Dim Row_3 As PORTB.3
Dim Row_2 As PORTB.4
Dim Row_1 As PORTB.5

//HEADLIGHT ON TRAIN ENGINE
Dim Head_light As PORTC.7

//CANDLE FLAMES
Dim Flame1 As PORTC.0
Dim Flame2 As PORTC.1
Dim Flame3 As PORTC.2

// SPRINKLES ANODES
Dim RED As PORTC.3
Dim WHITE As PORTC.4
Dim BLUE As PORTC.5
Dim GREEN As PORTC.6


  
Sub Sprinkles()
     // CYCLE THROUGH ENABLING THE ANODES and rows
     // LIGHT CANDLES
 //CANDLE FLAMES  ON SEQUENCLY  PORTC. 0,1,2
          Flame1 = 1
          DelayMS(2000)
          Flame2 = 1
          DelayMS(2000)
          Flame3 = 1   
          
//Row_1
    RED = 1
    WHITE=0
    BLUE = 0
    GREEN = 0
    Row_1 = 0
    Row_2 = 1
    Row_3 = 1
    Row_4 = 1
    DelayMS(10)
    Row_1 = 1
    Row_2 = 0
    Row_3 = 1
    Row_4 = 1
    DelayMS(10)
    Row_1 = 1
    Row_2 = 1
    Row_3 = 0
    Row_4 = 1
    DelayMS(10)
    Row_1 = 1
    Row_2 = 1
    Row_3 = 1
    Row_4 = 0
    DelayMS(10)
    
//ROW_2   
        
        RED = 0
        WHITE=0
        BLUE = 1
        GREEN = 0
        Row_1 = 0
        Row_2 = 1
        Row_3 = 1
        Row_4 = 1
        DelayMS(10)
        Row_1 = 1
        Row_2 = 0
        Row_3 = 1
        Row_4 = 1
        DelayMS(10)
        Row_1 = 1
        Row_2 = 1
        Row_3 = 0
        Row_4 = 1
        DelayMS(10)
        Row_1 = 1
        Row_2 = 1
        Row_3 = 1
        Row_4 = 0
        DelayMS(10)
        
      
//ROW_3                 
            RED = 0
            WHITE=0
            BLUE = 1
            GREEN = 0
            Row_1 = 0
            Row_2 = 1
            Row_3 = 1
            Row_4 = 1
            DelayMS(10)
            Row_1 = 1
            Row_2 = 0
            Row_3 = 1
            Row_4 = 1
            DelayMS(10)
            Row_1 = 1
            Row_2 = 1
            Row_3 = 0
            Row_4 = 1
            DelayMS(10)
            Row_1 = 1
            Row_2 = 1
            Row_3 = 1
            Row_4 = 0
            DelayMS(10)
            
//ROW_4               
                    RED = 0
                    WHITE=0
                    BLUE = 0
                    GREEN = 1
                    Row_1 = 0
                    Row_2 = 1
                    Row_3 = 1
                    Row_4 = 1
                    DelayMS(10)
                    Row_1 = 1
                    Row_2 = 0
                    Row_3 = 1
                    Row_4 = 1
                    DelayMS(10)
                    Row_1 = 1
                    Row_2 = 1
                    Row_3 = 0
                    Row_4 = 1
                    DelayMS(10)
                    Row_1 = 1
                    Row_2 = 1
                    Row_3 = 1
                    Row_4 = 0
                    DelayMS(10)
           End Sub

Sub Candles()
     If Flames = 0 Then   //toggle switch ON to ground
       Flame1 = 1
        DelayMS(1500)
       Flame2 = 1
        DelayMS(1500)
       Flame3 = 1
   EndIf
 
   If Flames = 1 Then   //toggle switch off disconnects ground
       Flame1 = 0       //turn these on sequently maybe 1500ms delay between each flane
       Flame2 = 0
       Flame3 = 0
   EndIf         
End Sub

Sub Head_light_Motion()     //needs work to flicker

        Head_light = 1
        DelayMS(250)
        Head_light = 0
        DelayMS(400)
        Head_light = 1
        DelayMS(400)

End Sub

// before enabling the outputs, init all LAT registers low
LATA = 0
LATB.0 = 0
LATB.1 = 1
LATB.2 = 0
LATB.3 = 0
LATB.4 = 0
LATB.5 = 0
LATB.6 = 0
LATB.7 = 0
LATC = 0


//ENABLE OUTPUTS  port A, B, C
TRISA = 0   
TRISB.0 = 0
TRISB.1 = 1    //input
TRISB.2 = 0
TRISB.3 = 0
TRISB.4 = 0
TRISB.5 = 0
TRISB.6 = 0
TRISB.7 = 0
TRISC = 0

//SPRINKLES COLUMS
RED = 0
WHITE=0
BLUE = 0
GREEN = 0
Input(Flames)
// MAKE ALL THE CATHODES LOW
Row_1 = 1
Row_2 = 1
Row_3 = 1
Row_4 = 1
Head_light = 0     //TOGGLETO  SIMULATE MOVEMENT


//TURN OFF THE LETTERING
R = 0
Y = 0
D = 0
E = 0
R_1 = 0
W = 0
O = 0
D_1 = 0

//TURN OFF THE RED STRIPS
  Red_Candle_STRIPS = 0
 
// TURN OFF FLAMES
Flame1 = 0     //portC.0
Flame2 = 0     //portC.1
Flame3 = 0     //portC.2
Input(Flames)     //connects to ground via toggle switch connected to portb.1 (flames)


time_delay = 0
'Z = 0
SetAllDigital()

 While true
 // Lettering comes on sequently 6 times
// z = 0
 repeat
        R = 1            //turn on lettering sequencly
        DelayMS(1500)
        Y = 1
        DelayMS(1500)
        D = 1
        DelayMS(1500)
        E = 1
        DelayMS(1500)
        R_1 = 1
        DelayMS(1500)
        W = 1
        DelayMS(1500)
        O = 1
        DelayMS(1500)
        D_1 = 1
        DelayMS(1500)
        
        
        For X = 0 To 5   //blink lettering 6 times   
                R = 0
                Y = 0
                D = 0
                E = 0
                R_1 = 0
                W = 0
                O = 0
                D_1 = 0         
             DelayMS(1500)
                R = 1
                Y = 1
                D = 1
                E = 1
                R_1 = 1
                W = 1
                O = 1
                D_1 = 1
             DelayMS(1500)
        Next
 Head_light_Motion()        //turn on headlight
        
 //TURN ON THE RED LED STRIPS (100 ON TOP OF CAKE)       
Red_Candle_STRIPS = 1  //turn on the red 100 on top of cake
time_delay = time_delay + 1
 until
time_delay = 240000              // 4 minutes when say 4 minutes have passed then the code recycles again

            
if flames = 0 then      // enable candle flames sequencing
 candles()
 end if
 
  
 

 
          
  
 
  
   Wend
 
Since you have a delay function provided by swordfish, just do 240 delay(1000) in a loop.

I have no idea how interrupts work in Swordfish and I don't want to know. Danadak is right about the volatile storage class in C. I'm embarrassed to have omitted that tip.

If you have any plans of doing a lot with microcontroller and especially if you have any idea of doing so professionally, please abandon swordfish and learn C. It's not that different. Languages like swordfish are suppose to make it easier to learn programming. But the thing is, learning the language syntax is not the hard part at all. The important and difficult parts are learning how to implement a solution, data structures, algorithms, when to use interrupts, etc. This won't be any easier with BASIC than with C and some important stuff is probably not available.
 

Pommie

Well-Known Member
Most Helpful Member
Some of the pic timers have a 16 bit mode (Timer 1 normally) so when you read the lower byte it buffers the high byte to avoid any interrupt (or increment) problems.

Mike.
transconductance , you'll learn in time, you can explain things in the most complete way and it will be completely ignored by the OP. Have a read of https://www.electro-tech-online.com/threads/junebug-help.91478/ from 13 years ago. I couldn't find the "critter Ridder" thread that went to 40 odd pages even though I posted working code on page 2.
Edit2, It was that thread, I posted complete working code here. It includes an Interrupt.
 
Last edited:
I get multiple emails per day and at least one call (two so far today) trying to hire an embedded C/C++ programmer. Nobody ever asks for a basic programmer. In fact, I've been doing this since before K&R came out and have never encountered swordfish basic until today.

But, you're right, Mike. I've noticed that there is a thread going today with tons of suggestions for a current limit when, in fact, the OP doesn't need a current limit at all and more than one person has explained this. I did manage to stay out of that one.

I try to answer posts that have 0 replies. Can't always do it because sometimes there's a good reason nobody has replied.
 

Pommie

Well-Known Member
Most Helpful Member
Swordfish is excellent and as flexible as C. But as you say, not mainstream like C/C++.

I find it interesting that ALL the Arduino libraries are written in C (actually C++) and I wonder who will write those libraries in the future. Bet they'll earn a fortune. You sound like you could be one of those people.

Can I ask, do you find your skills becoming more in demand as time moves forward?

Mike.
 
I'm not questioning whether it is any good and I'll take your word for it. But how much community support is there for it? It can't compare to C. Same for jobs. Now, he may not care. I have a good friend who refuses to learn C because (he thinks) FlowCode is all he needs. I've written proprietary language compilers myself. It's not evil. But I don't think it is a very good idea to start out there.

Also a blocking time delay is a red flag unless it's multi-threaded.

I do know a little bit about FlowCode because of Bill. If he wants a timer - it's built in. If he wants to drive an LCD display - it's built in. But if he wants to support a different LCD display that FlowCode doesn't have a driver for, then it's either ridiculously complicated or someone (like me) has to write it in C.

Demand for embedded C programming, in my experience has been growing for decades. This is only natural as more and more things have microcontrollers in them. I have one project in hand which is converting a PCBA full of op-amps to a microcontroller-based design. But, yes, it has really exploded recently. I think it is the same root cause as the global chip shortage. With the IOT crowd putting microcontrollers in everything from toys to toothbrushes, the fabs can't keep up. And someone has to develop the firmware for all of them. Case in point IoTP I do take on contract jobs and I have enough work to keep me busy for the next 9 months or so.
 

tumbleweed

Active Member
I've removed all the non-relevant code...
Code:
time_delay = 0
repeat
        DelayMS(1500)
        DelayMS(1500)
        DelayMS(1500)
        DelayMS(1500)
        DelayMS(1500)
        DelayMS(1500)
        DelayMS(1500)
        DelayMS(1500)
        
        For X = 0 To 5
             DelayMS(1500)
             DelayMS(1500)
        Next

        time_delay = time_delay + 1
 until time_delay = 240000              // 4 minutes when say 4 minutes have passed then the code recycles again
What in god's name would make you think that loop takes 4 minutes?

If you have any plans of doing a lot with microcontroller and especially if you have any idea of doing so professionally, please abandon swordfish and learn C.
The OP has not plans on becoming a professional programmer, and even if he did, are there other languages he shouldn't use? It's not the tool, it's the person in front of the keyboard.

That recommendation would be a total waste of time.
 

Nigel Goodwin

Super Moderator
Most Helpful Member
I find it interesting that ALL the Arduino libraries are written in C (actually C++) and I wonder who will write those libraries in the future. Bet they'll earn a fortune.
I would imagine they earn nothing from it, as they are free. As you 'corrected' they are written in C++, not C, which is what makes them so easy to use - and complicates things trying to port Arduino libraries to PIC's :D
 

Pommie

Well-Known Member
Most Helpful Member
I would imagine they earn nothing from it, as they are free.
They currently get nothing but their skill set is becoming more rare and I assume they will become more in demand. Plus, I doubt they don't earn from it as the chip manufacturer (or whatever the library is for) must employ these people to write the libraries. The fact WE get them for free does not mean the programmer didn't get paid.

Mike.
 

Nigel Goodwin

Super Moderator
Most Helpful Member
They currently get nothing but their skill set is becoming more rare and I assume they will become more in demand. Plus, I doubt they don't earn from it as the chip manufacturer (or whatever the library is for) must employ these people to write the libraries. The fact WE get them for free does not mean the programmer didn't get paid.

Mike.
No, the libraries are almost entirely written by the public, for their own use and then shared - a few, like SparkFun ones, are written by programmers within the company, in order to promote products they sell that use the libraries.
 

Pommie

Well-Known Member
Most Helpful Member
No, the libraries are almost entirely written by the public, for their own use and then shared
If that is true then once all the programmers that can write libraries are "gone", who will write them? Must admit, I've written one such library without getting payed but just keep it to myself.

Mike.
 

Nigel Goodwin

Super Moderator
Most Helpful Member
If that is true then once all the programmers that can write libraries are "gone", who will write them? Must admit, I've written one such library without getting payed but just keep it to myself.

Mike.
Why will they be 'gone'? - there's a never ending stream of new programmers coming along - while C/C++ is an older language now, more modern languages are very similar, and it would be easy for future programmers to use C/C++ if there was any need to.

Historically Pascal was always taught at Universities, because it's a far better teaching language than C. Once students had learnt good programming practice, hopefully they would continue those while using other languages.

The simple BASIC compiler I 'wrote' for WinPicProgB was sent to me as partially written Visual BASIC code by a user of WinPicProg, which I rewrote/converted to Delphi/Pascal, and considerably extended.

The interesting point was that it was full of GOTO's - which are a big no/no in Pascal, and while I eliminated most of them there were a couple I couldn't get rid of, without an even larger rewrite. Pascal provides GOTO, but I'd NEVER used it before - and I had to consult a Pascal book to find it's syntax :D
 

MrDEB

Well-Known Member
referring to post#12 the 4 minutes comes from the REPEAT / UNTIL loop and adding 1 each loop
the DELAYMS(1500) are used to sequencly turn on the LED strips.
doing some testing today to see if my code works as planned.
 

tumbleweed

Active Member
Inside the repeat/until loop there are 20 calls to 'delayms(1500)'. That's 20 x 1500 = 30000 msecs worth of delay.

Ignoring all the led statements, that code is equivalent to:
Code:
counter = 0
repeat
    delayms(30000)        // 30 secs
    counter = counter + 1
until counter = 240000

If you test that code be prepared to wait a long time to get the results.
 

tumbleweed

Active Member
Every iteration through the loop you need to account for all the calls to delayms to get the total delay time for the repeat loop. Try something like:

Code:
dim time_delay as longword

// wait 't' msecs and incr global 'time_delay' variable
sub wait_delay(t as word)
    delayms(t)
    time_delay = time_delay + t
end sub

time_delay = 0
repeat
    // add your led statements and change all the calls to 'delayms()' to:
    wait_delay(1500)
    // other leds...
until (time_delay >= 240000)
 
Last edited:

Latest threads

New Articles From Microcontroller Tips

Top