Part 7 - Putting it all together

 A button could be useful for the final exercise, see below for how to attach one again. 

 

The circuit:

 

We now have the basis of our communication network and a way to interpret our messages. It is time to do something more interesting and creative and that is really up to you... 

There are many ways to make use of and interpret numbers in an interesting way, look at the Arduino reference page, check out things like arithmetic, maths functions, trigonometry, for loops etc. If you are feeling adventurous, you might research topics such as Conway's Game of Life, the Fibonacci Sequence, the Golden Ratiologarithmic spirals, Fractals, Markov chains, other probability models and ways of taming randomness. You might do something fantastically complicated and maths based, or you might just use for loops, delays and simple arithmetic to do some animation and sound control.

Remember, rules are good, restricting what you are allowed to do can be a great way of stimulating creativity and making the task seem more accessible! Maybe discuss this with your group and decide if you will have the same approach to your animations and forwarding node choice. 

Think about giving your nodes a personality, what natural models might you simulate? If your node hasn't had a communication for a while, will it get upset and interrupt the conversation? Will some of the nodes be cliquey and stick to speaking to other nodes in a small group? Will your node be loud and aggressive, or will it be quiet and passive? Can you use these simple devices to create a model that makes a comment about society, living organisms, evolution, political constructs, your own life or anything else that you have strong feelings about? Deep.

So:

  • Use the incoming value (0-1023) to control your LED and buzzer in an interesting way
  • Send out a meaningfully adapted integer between 0-1023 to another node, you might just hard code a node to send to or dynamically choose one, again discuss as a group
  • Someone will need to start the sequence, so at least one persons node should have a button and code to get it rolling, but you may find other uses for a button...

+ The solution


There is no solution as such, but if you need some help... I wanted to make use of the 'sin()' function to create an animation based on a sin wave. Trigonometry is not my forte but I found a great tutorial for using 'sin()' to fade an LED. I adapted it to control my LED and buzzer animations and transform the input number into another to spit out, check it out below:

/* 
 *  Uses the incoming number to control 
 *  elements of an operation based around 
 *  sin() trigonometry function. 
 *  The sin function controls animation of
 *  the LED and buzzer and decides what 
 *  number to send out
 * 
 * 
 * Luke Woodbury 25 Jan 2017
 * dotLib.org
 */


//button pin and variable to store state
const int buttonPin = 12;
int buttonState = 0; 

//LED pins and variables to store values
const int redPin = 10; 
const int grnPin = 9;  
const int bluPin = 6;  
int redVal = 0;
int grnVal = 0;
int bluVal = 0;

//buzzer pin and variable
const int buzzPin = 11;
int toneVal = 100;

int thisNode = 1;
int nextNode = 2;

int TX = 0;

void setup()
{
  //set up serial for the xbee comms
  Serial1.begin(9600);
  //set up serial for printing to monitor etc
  //Serial.begin(9600);
  pinMode(redPin, OUTPUT);   // sets the pins as output
  pinMode(grnPin, OUTPUT);   
  pinMode(bluPin, OUTPUT); 

  pinMode(buttonPin, INPUT);  //...and input
}

void loop(){
  //check the button state
  buttonState = digitalRead(buttonPin);
  
  //if button is pressed do something
  if (buttonState == HIGH){
    //use random to create a code
    int code = random(1024);
    doIt(code);
    myAnim(code);
    allStop();
    delay(1000);
    sender(code);
  }

  if (Serial1.available() >= 3) {
    //use 'parseInt' to set the address/code variable 
    int address = Serial1.parseInt();
    int code = Serial1.parseInt();
    //Serial.print(address);
    //Serial.print(" ");
    //Serial.println(code);
    
    //if address matches our node number
    if(address == thisNode){
      int code = random(1024);
      doIt(code);
      myAnim(code);
      allStop();
      delay(1000);
      sender(TX); 
    }
  }
}

void doIt(int code){
    LEDanimate(code);
    playTone(code);
    delay(250);
}


void LEDanimate(int LEDval){
  
  if (LEDval < 341)  // Lowest third of the pot range (0-340)
  {                  
    LEDval = (LEDval * 3) / 4; // Normalize to 0-255

    redVal = 256 - LEDval;  // Red from full to off
    grnVal = LEDval;        // Green from off to full
    bluVal = 1;             // Blue off
  }
  else if (LEDval < 682) // Middle third of pot range (341-681)
  {
    LEDval = ( (LEDval-341) * 3) / 4; // Normalize to 0-255

    redVal = 1;            // Red off
    grnVal = 256 - LEDval; // Green from full to off
    bluVal = LEDval;       // Blue from off to full
  }
  else  // Upper third of potentiometer"s range (682-1023)
  {
    LEDval = ( (LEDval-683) * 3) / 4; // Normalize to 0-255

    redVal = LEDval;       // Red from off to full
    grnVal = 1;            // Green off
    bluVal = 256 - LEDval; // Blue from full to off
  }
  analogWrite(redPin, redVal);   // Write values to LED pins
  analogWrite(grnPin, grnVal); 
  analogWrite(bluPin, bluVal);  
}

void playTone(int toneVal){
  toneVal = map(toneVal, 0, 1023, 220, 4400);
  tone(buzzPin, toneVal);
}

void allStop(){
  analogWrite(redPin,0);
  analogWrite(grnPin,0);
  analogWrite(bluPin,0);
  noTone(buzzPin);
}


void myAnim(int code){
  float in, out;
  float rate = code * 0.00001;
  float topVal = (code * 0.001)+5.5;
  for (in = 0; in < topVal; in = in + rate){ //0.01){
    out = sin(in) * 511.5 + 511.5;
    LEDanimate(out);
    playTone(out);
  }
  TX = (out*2);
  TX = constrain(TX, 0, 1024);
  doIt(TX);
  Serial.println(TX);
}

void sender(int code){
    //Send to the next node
    Serial1.print(nextNode);
    Serial.print(nextNode);
    //send a space
    Serial1.print(' ');
    Serial.print(' ');
    //... then send the code
    Serial1.print(code);  
    Serial.println(code); 
 //...then another space to stop parseInt waiting
    Serial1.print(' ');  
}