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.

PIC16F628A PWM for LED Chaser

Status
Not open for further replies.
I tried a few values there. It was 9 originally. I changed it to 1 and then changed it to 128, but I couldn't tell a difference.
 
It definitely changes for me!
At 9, it's around one second per cycle; at 18, around 2 seconds.

Just a thought - if you are now using the "production" build, that does not automatically download to the IC, as the debug command does. You also need to hit the green down-arrow button to transfer the new build to the device.
Are you doing that?
 
You are changing the value in the #define line as below?

// Master, coarse speed setting value; larger is slower.
#define SUBSTEP_MAX 9

Then rebuild (Production > Clean and build) , then reprogram.

That definitely works to change the speed..

I'm using an ICD3 rather than PICKIT, but I cannot see it would need anything different?
 
Are you using the whole program from post #54, or have you cut and pasted parts of that and an older version?

The earlier versions has a constant further down, rather than the #define value, eg.

// Substep limit sets the overall cycle speed
substep = substep + 1;
if(substep > 4) {
 
I just redid the process and now it is working as it should. I do think I remember just copying the code into the original project. Sorry about that and thank you.
 
So, I have the details down about adding/removing LEDs from the mix by adjusting the offsets based on the "Step_Max." That works good, but when I do that, it leaves the LEDs that I "removed" lit all the time. I did uncomment "PORTA = outimg;" and commented "PORTA = ~outimg;" so the LEDs would be off. Is that just the nature of the beast and I just need to physically remove the LEDs as well?
 
Hi Mike,
I normally use interrupts and as many of the device hardware facilities as possible when working on our products, but as an example for someone just learning C, I tried to keep my example program as straightforward as possible; no interrupts, no special hardware features & no C shortcuts or compound operations.

I know it can be made rather faster and far more code efficient, but at the cost of functional clarity & I thought that was most important.

(The gamma correction in your other article is something I thought it needed, though. It needs more PWM levels ideally to work well with that).
Hi Robert & rescue161:

Forgive me, guys. I was just trying to help.

I was curious, though, so I attempted a version of Robert's example program with a toggle table PWM driver in the main loop. Here's an excerpt, if you're at all interested...

Cheerful regards...

Code:
/*********************************************************************
 *                                                                   *
 *********************************************************************/
 void main()
 { unsigned char step = 0;              // PWM step, 0..63
   unsigned char index = 0;             // image index, 0..119
   unsigned char speed = 0;             // PWM frames per image step

   unsigned char toggle[64] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
                                0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
                                0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
                                0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 };
   
   ANSELA = 0b00000000;                 //
   TRISA = 0b00000000;                  //
   LATA = 0b00111111;                   // for active lo LEDs
// LATA = 0b00000000;                   // for active hi LEDs

   while(1)                             //
   { index = 120;                       //
     while(index--)                     //
     { speed =  1;                      // speed, 1..255
   /*
    *  speed =  1 ->   210,136 cycles (  26.267-ms)
    *  speed = 10 -> 2,091,736 cycles ( 261.467-ms)
    *  speed = 20 -> 4,182,136 cycles ( 522.767-ms)
    *  speed = 40 -> 8,362,936 cycles (1045.367-ms)
    */
       do                               //
       { step = 0;                      // 64 step PWM period
         do                             //  "
         { LATA ^= toggle[step];        // 25 cycle (3.125-us) steps
           toggle[step] = 0;            //  "
           step++;                      //  "
         } while(step<64);              // 1672 cycle (209-us) period
   /*
    *  rebuild toggle array (71 cycles, 8.875-usecs)
    */
         toggle[img1[index+ 0]] |= 1;   // insert LED0 (RA0) toggle bit
         toggle[img1[index+24]] |= 2;   // insert LED1 (RA1) toggle bit
         toggle[img1[index+48]] |= 4;   // insert LED2 (RA2) toggle bit
         toggle[img1[index+72]] |= 16;  // insert LED3 (RA4) toggle bit
         toggle[img1[index+96]] |= 32;  // insert LED4 (RA5) toggle bit
         toggle[0] ^= ~LATA;            // initialize first element
       } while(--speed);                //
     }                                  //
   }                                    //
 }                                      //
Code:
/*
 *  120 steps, 3' per step.
 */

  const uint8_t  img1[] =
  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 4, 10, 24,
    32, 24, 10, 4, 2, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,

    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 4, 10, 24,
    32, 24, 10, 4, 2, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
 

Attachments

  • toggle table.jpg
    toggle table.jpg
    141.1 KB · Views: 208
  • flasher.c
    6.4 KB · Views: 202
Last edited:
rescue161,

is this 5 LED circuit & software a learning exercise? are you still shooting for a 12 LED solution?
 
It is just a small project that I thought would be easy...lol I want to have different beacons for RC cars. I wanted them to be replicas of single beacon rotators as well as multi-rotator lightbars, so I want the ability to run 12 (or more LEDs) for some lights and down to 4 LEDs for others. The LED lightheads that I have soldered up for testing are either 12, 8 or 6 LEDs each. With the code that I've been tweaking that rjenkinsgb provided, I am able to get it working for all of my variables, but when I use less than 5, which I have to on the 16F18313, the unused LEDs remain solid. It is no big deal as I can just remove them from the circuit or use them the solid LEDs as another light that is required to be on constantly while the beacon is on.
 
Forgive me, guys. I was just trying to help.

I was curious, though, so I attempted a version of Robert's example program with a toggle table PWM driver in the main loop. Here's an excerpt, if you're at all interested...
Hi Mike,

No complaints, it's all very interesting!
That method does make it a lot smaller and faster.

ps. The values in the step table are still set for 32 level PWM - I'm assuming they should be scaled for the updated 64 bit range.



rescue161
You can AND or OR the outimg variable with a bitmask just before copying it to a port, to force any pins you want to a specific state.

eg.
outimg |= 0x40;
would set RA5 high.

outimg &= 0x07;
would force everything other than RA0-2 low.

For more outputs, use a higher pin count PIC and eg. outimga + outimgb variables for the LEDs then transfer them to port a & b respectively.
 
Excellent. Thank you. I'm getting more comfortable with understanding the code. I'm also trying to make it through the XC Compiler Guide. Trying to learn C, Asm and PIC programming at the same time is very overwhelming.
 
Just finding out the meanings for all of the little "codes." Now, I can start to really see workings. I didn't know that & was AND and | was OR. It is all making much more sense now. I'm going to start migrating this over to a different PIC and I'll report back how I do. Thank you very much for the outstanding help in helping me figure this out. I hate having to be spoon-fed, but I guess that is what it took for me to finally get it. I have adjusted the PWM and the timing on the little 16F18313 and it is very smooth on the 3 & 4 LED lights. Now the wheels are turning in my head for what to do with all of the PICs that I bought...lol
 
Alright, I got the larger PIC programmed and it is working great. Had to read a little more and figured out my errors. Getting a better understanding, but have a LONG way to go. There is a lot of 'pointing to other areas' to either get info or to turn things on/off and if you don't remember, you'll point to an area that isn't there. That is what got me earlier.

I did find the memory limitations on the little 8-pin 16F18313, so I had to trim some tables. I was able to load all of the tables that I created into the 16F18426 and now have 11 outputs. So far, so good. Now I should be able to scale up/down as needed. I really do appreciate the help in getting me going. It wasn't clicking earlier, but everything has come together nicely. Thank you!
 
Last edited:
I want to thank you guys for helping me get my project started. I was lost, but thankfully, due to your explanations and help with coding, I was able to put together a relatively simple circuit to mimic the old Twin Sonic lightbars from the 1970s. The first one I made was on very thin double-sided FR4 and I made it to California specs with the solid red light facing forward and the flashing amber to the rear.


The second one was a test using the smaller PIC16F18313. I drilled out a 10mm LED and soldered four small LEDs and put them inside of the larger one. It turned out okay and I may use that setup to incorporate into an Aerodynic lightbar that has single light rotators that are sync'd together.


The latest one is why I started this project. It is an amber Twin Sonic that I plan to put on an RC tow truck that I'll get around to making... one day.


I'm still trying to figure out the best way to make the lenses. I have some thin clear sheets that I'm hoping to vacuum form or some how mold into shape. I do have some plastic sheets that I plan to use for the frame and housing. I'll get around to finishing it up one day. The Covid-19 schedule allowed me to toy around and get it working, but we went back to a full-time schedule, so I don't have as much free time to finish these projects. I'll finish them eventually. Again, thank you very much for all of the wonderful advice.

Scott
 
Thanks. I just used a Dremel and hollowed out the inside. I went a little too deep, but I centered the LEDs and filled it with clear glue. I'll probably use it on one of my RC planes. The LEDs that I used are 1608 SMD. They were a little hard to get straight, so one is a little off. It isn't too noticeable now that they are centered in the LED housing. Next time, I'll try a different method to get everything more aligned. If I am able to get it a little smaller, I can probably fit the 4 LEDs inside of a 5mm LED. I'm getting old and these little SMD components are getting hard to see though...
 
Status
Not open for further replies.

New Articles From Microcontroller Tips

Back
Top