outputs on/off , setting random pattern ?

Thread Starter

Gag14

Joined Jan 23, 2018
23
Hi
I have a question

lets say I have 3 outputs
and they can be set
001
next sec
100
next sec
010
and so on
but this setting is programmed, how to make them to go on and off randomly ?
I know how to do it on 2 chips , but is it possible to do it on one chip ?
thank you
 

JohnInTX

Joined Jun 26, 2012
4,787
Depends on how random you want but sure, any small PIC would do the job along with many other uCs. Create 3 timers in software to control the blinking. If using PIC and XC8, reload each using the random number function RAND() for varying on/off times.
 

Thread Starter

Gag14

Joined Jan 23, 2018
23
Depends on how random you want but sure, any small PIC would do the job along with many other uCs. Create 3 timers in software to control the blinking. If using PIC and XC8, reload each using the random number function RAND() for varying on/off times.
thanks
I didnt get the idea,

it would be one scan for all timers ? not random ,
can you explain more about .
yes I want it random .
 

JohnInTX

Joined Jun 26, 2012
4,787
Just thinking off the top of my head, consider setting up 3 count down registers loaded with different initial values with LEDs off.
Periodically, 1msec or so, decrement all of them.
Inspect each one for a value 0f 0. For each register that is 0 toggle the LED associated with that timer and reload the timer to a random value using LEDtimer_x = RAND(); It could be as simple as a dumb delay for the time base or an interrupt-driven periodic timer if you have other things to do.

Here's a framework to consider. It uses a 10F320 and compiles with XC8 in FREE mode with room to spare. I didn't assign the IO or fill in the macros for delay or TOGGLE_LED but you get the idea. I didn't test it but it's a reasonable starting point to illustrate making multiple timers. You may have to diddle with the numbers returned by rand() to limit the time settings to something usable. If the clock is slow enough and you use the full value from rand(), you might not need the delay at all.
Have fun!

C:
/*
* File:  RandomLED.c
* Author: JohnInTX
* PIC10F320 FREE MODE
* Created on February 16, 2018, 1:57 PM
*/

#include <xc.h>
#include <stdlib.h>

void main(void) {
  int LEDtimer_1, LEDtimer_2, LEDtimer_3;  // 3 separate timers

  LEDtimer_1 = LEDtimer_2 = LEDtimer_3 = 0;  // prime timers for reload

  while(1){

  if (LEDtimer_1) --LEDtimer_1;  // iff timer >0, decrement it
  else{
  LEDtimer_1 = rand();  // else, reload it with random value
  TOGGLE_LED_1;  // and toggle the associated LED
  }

  if (LEDtimer_2) --LEDtimer_2;
  else{
  LEDtimer_2 = rand();
  TOGGLE_LED_2;
  }

  if (LEDtimer_3) --LEDtimer_3;
  else{
  LEDtimer_3 = rand();
  TOGGLE_LED_3;
  }

  delay_1msec();  // dumb delay
  }//while
}
 
Last edited:

Thread Starter

Gag14

Joined Jan 23, 2018
23
Just thinking off the top of my head, consider setting up 3 count down registers loaded with different initial values with LEDs off.
Periodically, 1msec or so, decrement all of them.
Inspect each one for a value 0f 0. For each register that is 0 toggle the LED associated with that timer and reload the timer to a random value using LEDtimer_x = RAND(); It could be as simple as a dumb delay for the time base or an interrupt-driven periodic timer if you have other things to do.

Here's a framework to consider. It uses a 10F320 and compiles with XC8 in FREE mode with room to spare. I didn't assign the IO or fill in the macros for delay or TOGGLE_LED but you get the idea. I didn't test it but it's a reasonable starting point to illustrate making multiple timers. You may have to diddle with the numbers returned by rand() to limit the time settings to something usable. If the clock is slow enough and you use the full value from rand(), you might not need the delay at all.
Have fun!

C:
/*
* File:  RandomLED.c
* Author: JohnInTX
* PIC10F320 FREE MODE
* Created on February 16, 2018, 1:57 PM
*/

#include <xc.h>
#include <stdlib.h>

void main(void) {
  int LEDtimer_1, LEDtimer_2, LEDtimer_3;  // 3 separate timers

  LEDtimer_1 = LEDtimer_2 = LEDtimer_3 = 0;  // prime timers for reload

  while(1){

  if (LEDtimer_1) --LEDtimer_1;  // iff timer >0, decrement it
  else{
  LEDtimer_1 = rand();  // else, reload it with random value
  TOGGLE_LED_1;  // and toggle the associated LED
  }

  if (LEDtimer_2) --LEDtimer_2;
  else{
  LEDtimer_2 = rand();
  TOGGLE_LED_2;
  }

  if (LEDtimer_3) --LEDtimer_3;
  else{
  LEDtimer_3 = rand();
  TOGGLE_LED_3;
  }

  delay_1msec();  // dumb delay
  }//while
}
thank for work
At the moment my programming skills is assembler ... c is the next step ,
But i can see the idea ...
 

jpanhalt

Joined Jan 18, 2008
11,087
At the moment my programming skills is assembler
There is a method for calculating "pseudo" random numbers called "Linear Feedback Shift Registers (LFSR)."
It's not very random, but it is easy to program. Here is one of the simplest descriptions I have of it: https://www.eetimes.com/document.asp?doc_id=1274550&print=yes

Just use btfss to decide what to feed into your 3-bit value. Basically, you do a parity test for the "taps" of the current value. Take a stab at it. Unfortunately, with just 3 bits, most people will see the pattern quickly.

Edit: With such a small number of possible values, I might just make a table of "random" values and use some simple way to chose my pointer/jump value. The table might actually be shorter code.
 
Last edited:

JohnInTX

Joined Jun 26, 2012
4,787
There is a method for calculating "pseudo" random numbers called "Linear Feedback Shift Registers (LFSR)."
It's not very random, but it is easy to program. Here is one of the simplest descriptions I have of it: https://www.eetimes.com/document.asp?doc_id=1274550&print=yes

Just use btfss to decide what to feed into your 3-bit value. Basically, you do a parity test for the "taps" of the current value. Take a stab at it. Unfortunately, with just 3 bits, most people will see the pattern quickly.

Edit: With such a small number of possible values, I might just make a table of "random" values and use some simple way to chose my pointer/jump value. The table might actually be shorter code.
I didn't think about LFSRs. Brilliant! Your link is a nice review of the subject, too.
 

jpanhalt

Joined Jan 18, 2008
11,087
@Gag14
Unless you have something working already, would you please let us know which MCU, port, and pins of that port you are using. Assuming that port is 8-bit, are the other pins of that port used for anything else?
 

Thread Starter

Gag14

Joined Jan 23, 2018
23
@Gag14
Unless you have something working already, would you please let us know which MCU, port, and pins of that port you are using. Assuming that port is 8-bit, are the other pins of that port used for anything else?
I was thinking to use a 16f628a and just two ports , can be B0, and B1 , they should turn on and off for .25 sec . I like the LFSRs idea. Or maybe I will have two chips and then it would be much easy and they will go on/off randomly (outputs).
 

jpanhalt

Joined Jan 18, 2008
11,087
Unless your 16F628A is doing a lot of other stuff, there is no need for two chips.

As for the pins, you do mean RB0,RB1, and RB2, right? (You need three pins for 3 LEDs, unless you are multiplexing them.)

My question about what else was on the port (e.g, bits 7:3) has to do with how you set and change your outputs. For example, if there is nothing on those pins, then you can just move an 8-bit register to that port with the lower three bits set properly. If those pins are being used for other things, then you will have to set the pins separately. That is not hard to do using rotates or logic (e.g., and's and or's). It is just more code.

Edit: If the other pins are used, are they inputs or outputs? Which are which?

John
 
Last edited:

Thread Starter

Gag14

Joined Jan 23, 2018
23
Unless your 16F628A is doing a lot of other stuff, there is no need for two chips.

As for the pins, you do mean RB0,RB1, and RB2, right? (You need three pins for 3 LEDs, unless you are multiplexing them.)

My question about what else was on the port (e.g, bits 7:3) has to do with how you set and change your outputs. For example, if there is nothing on those pins, then you can just move an 8-bit register to that port with the lower three bits set properly. If those pins are being used for other things, then you will have to set the pins separately. That is not hard to do using rotates or logic (e.g., and's and or's). It is just more code.

Edit: If the other pins are used, are they inputs or outputs? Which are which?

John
 

Thread Starter

Gag14

Joined Jan 23, 2018
23
My question was a general question , is it possible to have a random pattern with one clock ?
I see with logic operations it is possible to do it ,
Can you give some examples? in assembler ? just the idea . Basically I need only 2 ports to switch , lets say
the whole chip works for the switching , nothing else .
thank you
 

jpanhalt

Joined Jan 18, 2008
11,087
You can produce pseudo random numbers or as random as you are likely to get with any MCU with a single clock. LFSR will produce a repeating sequence with a repeat period that depends on the size of the seed number -- with just three bits it will be easy to recognize the repeat unit. With 4-bytes, it is much more difficult for humans alone to recognize the sequence. Other methods, such as looking at noise on the mains produce better randomness.

Because the repeat period is just 7 with 3 bits, I played with two other approaches with longer repeat periods. One was to use an 8-bit seed and 3 taps (period = 255) and just record the lower 3 bits. There were (as expected) obvious repeating sequences therein. I did not look at its output carefully though. The other approach was to make a table of arbitrary size of "random" numbers . Code wise, the former will be shorter. Appearance wise, the latter might be better. For the table, I used sequential digits of pi that were ≤ 7.

Here are the first 47, 3-bit values using LFSR with an 8-bit seed : 0012413765364124124364000013765241240137640124 Notice: after a 2, there is always a 4. I bolded another of several obvious sequences.

Here's the pi-based sequence (n=80):
6043702770532171762317676234674146766405132
0005612714526356027757713427577601736371772

Both examples were done with assembly, but recently, I have only been using the enhanced mid-range chips. The code is easily adapted to the 16F628A, but cannot do it right now.

John
 

Thread Starter

Gag14

Joined Jan 23, 2018
23
You can produce pseudo random numbers or as random as you are likely to get with any MCU with a single clock. LFSR will produce a repeating sequence with a repeat period that depends on the size of the seed number -- with just three bits it will be easy to recognize the repeat unit. With 4-bytes, it is much more difficult for humans alone to recognize the sequence. Other methods, such as looking at noise on the mains produce better randomness.

Because the repeat period is just 7 with 3 bits, I played with two other approaches with longer repeat periods. One was to use an 8-bit seed and 3 taps (period = 255) and just record the lower 3 bits. There were (as expected) obvious repeating sequences therein. I did not look at its output carefully though. The other approach was to make a table of arbitrary size of "random" numbers . Code wise, the former will be shorter. Appearance wise, the latter might be better. For the table, I used sequential digits of pi that were ≤ 7.

Here are the first 47, 3-bit values using LFSR with an 8-bit seed : 0012413765364124124364000013765241240137640124 Notice: after a 2, there is always a 4. I bolded another of several obvious sequences.

Here's the pi-based sequence (n=80):
6043702770532171762317676234674146766405132
0005612714526356027757713427577601736371772

Both examples were done with assembly, but recently, I have only been using the enhanced mid-range chips. The code is easily adapted to the 16F628A, but cannot do it right now.

John
 
Top