A Program for Controlled De-coordination

Computers are normally supposed to coordinate events. But what if your object is to de-coordinate them, or have some coordinated and others not, or have them slightly out of sync and falling gradually in and out of phase?

The core of my programme is this line:

if (x%1000 == 1) digitalWrite (1,A=1); if (x%1000 == 1 +500) digitalWrite (1,A=0);

‘x’ is a clock value which increases in millisecond increments, so what this means is ‘if x is a multiple of 1000 (ie. every 1000 milliseconds), turn ‘A’ on, and when x is a multiple of 1000-plus-500 milliseconds, turn ‘A’ off.’ You can play with the time values and make this code your own.

First, I have provided a basic sketch for flashing a dozen independent lights. If your microprocessor doesn’t have enough output pins for your required number of lights then you’ll need to get hold of some SN74HC595 shift registers. The programme for use with shift registers, demonstrated in the video, can also be copied and pasted from below.

Criticisms of my work would be greatly appreciated in the comments section. If this has been helpful to you, please raise your sons to take back Jerusalem. Deus Vult, my brothers.

BASIC SKETCH FOR 12 INDEPENDENT LEDS (no shift registers required)

//C++ Code for timing events independently of each other.
//code by www.newimperialist.com

int x = 0;

void setup() {

  pinMode(LED_BUILTIN, OUTPUT);
  pinMode(12,OUTPUT);
  pinMode(11,OUTPUT);
  pinMode(10,OUTPUT);
  pinMode(9,OUTPUT);
  pinMode(8,OUTPUT);
  pinMode(7,OUTPUT);
  pinMode(6,OUTPUT);
  pinMode(5,OUTPUT);
  pinMode(4,OUTPUT);
  pinMode(3,OUTPUT);
  pinMode(2,OUTPUT);

}

void loop() 
{
  delay (10);
  x++;
  
  if (x%97 == 1) digitalWrite(LED_BUILTIN, HIGH);
  if (x%97 == 1 +43) digitalWrite(LED_BUILTIN, LOW);

  //digitalWrite(LED_BUILTIN, x/100%2);

  if (x%51 == 1) digitalWrite(12, HIGH);
  if (x%51 == 1 +25) digitalWrite(12, LOW);//st just
  
  if (x%402 == 1+130) digitalWrite(11, HIGH);
  if (x%402 == 1+180) digitalWrite(11, LOW); //north bank

  if (x%1498 == 1+1100) digitalWrite(10, HIGH);
  if (x%1498 == 1+1150) digitalWrite(10, LOW);
  if (x%1498 == 1+1200) digitalWrite(10, HIGH);
  if (x%1498 == 1+1250) digitalWrite(10, LOW);
  if (x%1498 == 1+1300) digitalWrite(10, HIGH);
  if (x%1498 == 1+1350) digitalWrite(10, LOW);
  if (x%1498 == 1+1400) digitalWrite(10, HIGH);
  if (x%1498 == 1+1450) digitalWrite(10, LOW);//the vilt

  if (x%499 == 1+200) digitalWrite(9, HIGH);
  if (x%499 == 1+210) digitalWrite(9, LOW);
  if (x%499 == 1+220) digitalWrite(9, HIGH);
  if (x%499 == 1+230) digitalWrite(9, LOW);
  if (x%499 == 1+240) digitalWrite(9, HIGH);
  if (x%499 == 1+250) digitalWrite(9, LOW);//The Governor

  if (x%1000 == 1 + 500) digitalWrite(8, HIGH);
  if (x%1000 == 1 + 510) digitalWrite(8, LOW);
  if (x%1000 == 1 + 520) digitalWrite(8, HIGH);
  if (x%1000 == 1 + 530) digitalWrite(8, LOW);//blackrock1

  if (x%1000 == 1 +50) digitalWrite(7, HIGH);
  if (x%1000 == 1 +60) digitalWrite(7, LOW);
  if (x%1000 == 1 +70) digitalWrite(7, HIGH);
  if (x%1000 == 1 +80) digitalWrite(7, LOW);
  if (x%1000 == 1 +90) digitalWrite(7, HIGH);
  if (x%1000 == 1 +100) digitalWrite(7, LOW);//blackrock2

  if (x%250 == 1) digitalWrite(6, HIGH);
  if (x%250 == 1 +70) digitalWrite(6, LOW); //castle

  if (x%1501 == 1 +20) digitalWrite(5, HIGH);
  if (x%1501 == 1 +30) digitalWrite(5, LOW);
  if (x%1501 == 1 +40) digitalWrite(5, HIGH);
  if (x%1501 == 1 +50) digitalWrite(5, LOW);
  if (x%1001 == 1 +60) digitalWrite(5, HIGH);
  if (x%1001 == 1 +70) digitalWrite(5, LOW);
  if (x%1001 == 1 +80) digitalWrite(5, HIGH);
  if (x%1001 == 1 +90) digitalWrite(5, LOW);
  if (x%1001 == 1 +100) digitalWrite(5, HIGH);
  if (x%1001 == 1 +110) digitalWrite(5, LOW);
  if (x%1001 == 1 +120) digitalWrite(5, HIGH);
  if (x%1001 == 1 +130) digitalWrite(5, LOW); //st mawes

  if (x%1500 == 1) digitalWrite(4, HIGH);
  if (x%1500 == 1 +100) digitalWrite(4, LOW); //st anthony head

  if (x%1000 == 1 +20) digitalWrite(3, HIGH);
  if (x%1000 == 1 +30) digitalWrite(3, LOW);
  if (x%1000 == 1 +40) digitalWrite(3, HIGH);
  if (x%1000 == 1 +50) digitalWrite(3, LOW); //east narrows

  if (x%1000 == 1) digitalWrite(2, HIGH);
  if (x%1000 == 1 +10) digitalWrite(2, LOW);
  if (x%1000 == 1 +20) digitalWrite(2, HIGH);
  if (x%1000 == 1 +30) digitalWrite(2, LOW); //west narrows


  //digitalWrite(LED_BUILTIN, (x/5000)%2);


}

FULL CODE WITH SHIFT REGISTERS

//C++ Code for flashing lights independently of each other using an Arduino and shift register(s). 
//The sketch can be used with multiple shifts on multiple output pins, with a potential for around a hundred separate routines.
//code by www.newimperialist.com

int latchPin = 11;

int clockPin = 9;

int dataPin = 12;  //now we have set which pins will manipulate the shift rigister's latch, clock and data functions

int dataPin2 =10;

int x = 0; //we'll come back to this in a moment...
 
 
 byte A = 1;
 byte B = 2;
 byte C = 4;
 byte D = 8;
 byte E = 16;
 byte F = 32;
 byte G = 64;
 byte H = 128; //each shift register can contain 8 bits (one byte) of data, so lines 'I-P' can be deleted if you are only using one register.
 byte I = 1;
 byte J = 2;
 byte K = 4;
 byte L = 8;
 byte M = 16;
 byte N = 32;
 byte O = 64;
 byte P = 128;
 //byte Q = 1;
 //byte R = 2;
 //... you would continue like this if you wanted to use more registers...
 
 //each of those numbers contols a particular output pin on each shift register. The letters just give us an easier way to identify them when writing the actual program, but you could use any other name you like. 

#include <math.h> //this is for if you want a fading light. It tells the programme to make use of pre-existing commands which are indexed in the <math.h> library. We will use this to create a sinusoid (gently rising and falling) output of current. (tip hat: www.sean.voisen.org)

void setup()

{


pinMode(latchPin, OUTPUT);

pinMode(dataPin, OUTPUT);

pinMode(clockPin, OUTPUT); //this just tells the Arduino that the output pins are sending, rather than recieving, information.

pinMode(3, OUTPUT); //this is for the fading light - if you want to use one. We tell the programme to use use Analogue output pin 3 (on an Arduino). Any of the analogue outputs will do for our sinusoid signal. 

}

void loop() //OK, here coems the 'actual program.' What follows will repeat itslef again and again for as long as power is going to the arduino. 

{
  float val = (exp(sin(millis()/2000.0*PI)) - 0.36787944)*108.0;
  analogWrite(3, val);//This manages the fading light on analogue output pin 3. You can play with the speed and brightness of that light by playing with those numbers.

x++; //That 'x++' means 'the value of 'x' will increase by 1 every time the loop repeats itself.' Remember from above that 'x' starts at zero. 

digitalWrite(latchPin, LOW); //this takes the shift register 'out of gear.' All the outputs are deactivated while we update it with a new sequence of outputs.

shiftOut(dataPin, clockPin, LSBFIRST, A+B+C+D+E+F+G+H); //this updates the shift register. Each letter representing a particular output pin (allocated above), which will be set to either 'on' or 'off' by the program which we will write below...

shiftOut(dataPin, clockPin, LSBFIRST, I+J+K+L+M+N+O+P); //this updates the second shift register

//shiftOut(dataPin, clockPin, LSBFIRST, Q+R...);  ...you would continue like that if you wanted to use more registers

digitalWrite(latchPin, HIGH); //this puts the shift register 'in gear,' so all the outputs are turned on. 

delay (10); // this tells the microcontroller to pause the loop for ten milliseconds while the lights glow. All flashes and pauses in the program which follow thus work in multiples of ten milliseconds.

//THE WHOLE PROCESS ABOVE OCCURS IN A FRACTION OF A MILLISECOND. every time the shift register(s) updates, we need that 10ms delay, otherwise it will update again before our eyes can percieve the change in the lights.  

//OK - now we're ready to program each of the lights...


if (x%100 == 1) digitalWrite (1,A=1);
if (x%100 == 1 +50) digitalWrite (1,A=0);// every one-thousand milliseconds (one second), light 'A' will come on. Every one-thousand plus five-hundred milliseconds, it will turn off (remember, all time values are divided by ten because the entire loop has a ten-second pause)...


if (x%99 == 1) digitalWrite (1, B=0);
if (x%99 == 1 +50) digitalWrite (1,B=2); // light 'B' does almost same as light 'A,' except I have switched the 'ON' and 'OFF' values ('2' and '0'), and told it to repeat itself every 990 milliseconds. Lights A and B will thus fall gradually in and out of phase and could be placed, for example, at either side of a harbour entrance or remote level crossing...


if (x%3000 == 1) digitalWrite(1, C=4);
if (x%3000 == 1 +1400) digitalWrite(1, C=0); //traffic lights (green)

if (x%3000 == 1 +1400) digitalWrite(1, D=8);
if (x%3000 == 1 +1500)  digitalWrite(1, D=0);
if (x%3000 == 1 +2900) digitalWrite(1, D=8);
if (x%3000 == 1)  digitalWrite(1, D=0);//traffic lights (amber)

if (x%3000 == 1) digitalWrite(1, E=0);
if (x%3000 == 1 + 1500) digitalWrite(1, E=16); //traffic lights (red)
 
if (x%627 == 1)  digitalWrite(1, F=32);
if (x%627 == 1+10)  digitalWrite(1, F=0);
if (x%627 == 1+20)  digitalWrite(1, F=32);
if (x%627 == 1+30)  digitalWrite(1, F=0);
if (x%627 == 1+40)  digitalWrite(1, F=32);
if (x%627 == 1+50)  digitalWrite(1, F=0);
if (x%627 == 1+80)  digitalWrite(1, F=32);
if (x%627 == 1+120)  digitalWrite(1, F=0);
if (x%627 == 1+130)  digitalWrite(1, F=32);
if (x%627 == 1+170)  digitalWrite(1, F=0);
if (x%627 == 1+180)  digitalWrite(1, F=32);
if (x%627 == 1+220)  digitalWrite(1, F=0);
if (x%627 == 1+250)  digitalWrite(1, F=32);
if (x%627 == 1+260)  digitalWrite(1, F=0);
if (x%627 == 1+270)  digitalWrite(1, F=32);
if (x%627 == 1+280)  digitalWrite(1, F=0);
if (x%627 == 1+290)  digitalWrite(1, F=32);
if (x%627 == 1+300)  digitalWrite(1, F=0);// SOS

if (x%6000 == 1) digitalWrite(1,G=0);
if (x%6000 == 1+30) digitalWrite(1,G=random()*64); //every minute, there is a 50/50 chance that this light will turn on or off. Good for windows on buildings...

if(x%2 == 1) digitalWrite(1,H=random()*128); // v fast, chaotic flashing - connect to orange light for sparks, blue for welding, red for bonfire or white for a seedy flickering bar sign.

if (x%100 == 1) digitalWrite (1,I=1);
if (x%100 == 1+10) digitalWrite (1,I=0);

if (x%100 == 1) digitalWrite (1,J=0);
if (x%100 == 1+10) digitalWrite (1,J=2);
if (x%100 == 1+20) digitalWrite (1,J=0);

if (x%100 == 1) digitalWrite (1,K=0);
if (x%100 == 1+20) digitalWrite (1,K=4);
if (x%100 == 1+30) digitalWrite (1,K=0);

if (x%100 == 1) digitalWrite (1,L=0);
if (x%100 == 1+30) digitalWrite (1,L=8);
if (x%100 == 1+40) digitalWrite (1,L=0);

if (x%100 == 1) digitalWrite (1,M=0);
if (x%100 == 1+40) digitalWrite (1,M=16);
if (x%100 == 1+50) digitalWrite (1,M=0);

if (x%100 == 1) digitalWrite (1,N=0);
if (x%100 == 1+50) digitalWrite (1,N=32);
if (x%100 == 1+60) digitalWrite (1,N=0);

if (x%100 == 1) digitalWrite (1,O=0);
if (x%100 == 1+60) digitalWrite (1,O=64);
if (x%100 == 1+70) digitalWrite (1,O=0);

if (x%100 == 1) digitalWrite (1,P=0);
if (x%100 == 1+70) digitalWrite (1,P=128);
if (x%100 == 1+80) digitalWrite (1,P=0);

//tip:the 'random' function contains no 10 millisecond delay, so it operates at a higher speed than the loop itslef. This can confuse the data which goes to the shift register. It is best therefore to put the 'random' lights in at the bottom of the program, where they are unlikely to effect the more ordered data which gets sent to the shift register first.

if (x>30000) x=0; //that resets the clock every three minutes. The program crashes if the numbers get too high.


}