interface and application programming


Assignment Requirements:

  • Group Assignment:
  • Individual Assignment:
  • Learning Outcomes:

  • Interpret and implement design and programming protocols to create a Graphic User Interface (GUI).

  • Steps in General:


    Introduction

    In this week I decided to build an application to control an addressable RGB LED strip through wifi, using the ESP 8266. This week is considered the interfacing window for my final project, as the user will open the application through his/her browser and type the component name, quantity and the required operation for inventory (either adding or picking up components).

    Steps in Details:

    Step(1): Creating a web interface using Bootstrap

    Snow
    Forest

    Step(2): Programming the ATMega 328p board

                                        
    
     #include "FastLED.h"
    
    // How many leds in your strip?
    #define NUM_LEDS 20
    #define DATA_PIN 6
    #define FORWARD 0
    #define BACKWARD 1
    #define SLOW 250
    #define MEDIUM 50
    #define FAST 5
    
    CRGB leds[NUM_LEDS];
    
    boolean direction = FORWARD;
    
    void setup() { 
      FastLED.addLeds< NEOPIXEL, DATA_PIN>(leds, NUM_LEDS);
      randomSeed(analogRead(0));
      Serial.begin(9600);
    }
    
    void loop() { 
    
      rainbow(0,NULL);
      delay(3000);
      colorWipe(CRGB::Black,FORWARD,FAST);
      allRandom();
      delay(3000);
      disolve(15,100,MEDIUM);
    
      for(int i=0; i<3; i++){
        CRGB c1 = randomColor();
        CRGB c2 = randomColor();
        stripes(c1,c2,5);
        delay(2000);
        stripes(c2,c1,5);
        delay(2000);
      }
    
      for(int i=0; i<2; i++){
        cylon(randomColor(), 10,FAST);
      }
    
    
      lightning(NULL,15,50,MEDIUM);
      lightning(CRGB::White,20,50,MEDIUM);
    
      for(int i=0; i<3; i++){
        theaterChase(randomColor(),10,SLOW);
      }
    
      theaterChaseRainbow(1,MEDIUM);
    
      rainbow(FAST,1);
    
      flash(randomColor(),10,SLOW);
    
      flash(NULL,50,MEDIUM);
    
      for(int i=0; i<2; i++){ 
        colorWipe(randomColor(),FAST,direction);
        direction = !direction;
      }
    
    
    }
    
    // Changes all LEDS to given color
    void allColor(CRGB c){
      for(int i=0; i< NUM_LEDS; i++){
        leds[i] = c;
      }
      FastLED.show();
    }
    
    void allRandom(){
      for(int i=0; i < NUM_LEDS; i++){
        leds[i] = randomColor();
      }
      FastLED.show(); 
    }
    
    // Random disolve colors
    void disolve(int simultaneous, int cycles, int speed){
      for(int i=0; i< cycles; i++){
        for(int j=0; j < simultaneous; j++){
          int idx = random(NUM_LEDS);
          leds[idx] = CRGB::Black;
        }
        FastLED.show();
        delay(speed);
      }
    
      allColor(CRGB::Black);
    }
    
    // Flashes given color
    // If c==NULL, random color flash
    void flash(CRGB c, int count, int speed){
      for(int i=0; i< count; i++){
        if(c){
          allColor(c);
        }
        else{
          allColor(randomColor());
        }
        delay(speed);
        allColor(CRGB::Black);
        delay(speed);
      }
    }
    
    // Wipes color from end to end
    void colorWipe(CRGB c, int speed, int direction){
      for(int i=0; i< NUM_LEDS; i++){
        if(direction == FORWARD){
          leds[i] = c;
        }
        else{
          leds[NUM_LEDS-1-i] = c;
        }
        FastLED.show();
        delay(speed);
      }
    }
    
    // Rainbow colors that slowly cycle across LEDs
    void rainbow(int cycles, int speed){ // TODO direction
      if(cycles == 0){
        for(int i=0; i< NUM_LEDS; i++) {
          leds[i] = Wheel(((i * 256 / NUM_LEDS)) & 255);
        }
        FastLED.show();
      }
      else{
        for(int j=0; j<256*cycles; j++) {
          for(int i=0; i< NUM_LEDS; i++) {
            leds[i] = Wheel(((i * 256 / NUM_LEDS) + j) & 255);
          }
          FastLED.show();
          delay(speed);
        }
      }
    }
    
    // Theater-style crawling lights
    void theaterChase(CRGB c, int cycles, int speed){ // TODO direction
    
      for (int j=0; j< cycles; j++) {  
        for (int q=0; q < 3; q++) {
          for (int i=0; i < NUM_LEDS; i=i+3) {
            int pos = i+q;
            leds[pos] = c;    //turn every third pixel on
          }
          FastLED.show();
    
          delay(speed);
    
          for (int i=0; i < NUM_LEDS; i=i+3) {
            leds[i+q] = CRGB::Black;        //turn every third pixel off
          }
        }
      }
    }
    
    // Theater-style crawling lights with rainbow effect
    void theaterChaseRainbow(int cycles, int speed){ // TODO direction, duration
      for (int j=0; j < 256 * cycles; j++) {     // cycle all 256 colors in the wheel
        for (int q=0; q < 3; q++) {
          for (int i=0; i < NUM_LEDS; i=i+3) {
            int pos = i+q;
            leds[pos] = Wheel( (i+j) % 255);    //turn every third pixel on
          }
          FastLED.show();
    
          delay(speed);
    
          for (int i=0; i < NUM_LEDS; i=i+3) {
            leds[i+q] = CRGB::Black;  //turn every third pixel off
          }
        }
      }
    }
    
    // Random flashes of lightning
    void lightning(CRGB c, int simultaneous, int cycles, int speed){
      int flashes[simultaneous];
    
      for(int i=0; i< cycles; i++){
        for(int j=0; j< simultaneous; j++){
          int idx = random(NUM_LEDS);
          flashes[j] = idx;
          leds[idx] = c ? c : randomColor();
        }
        FastLED.show();
        delay(speed);
        for(int s=0; s< simultaneous; s++){
          leds[flashes[s]] = CRGB::Black;
        }
        delay(speed);
      }
    }
    
    // Sliding bar across LEDs
    void cylon(CRGB c, int width, int speed){
      // First slide the leds in one direction
      for(int i = 0; i <= NUM_LEDS-width; i++) {
        for(int j=0; j< width; j++){
          leds[i+j] = c;
        }
    
        FastLED.show();
    
        // now that we've shown the leds, reset to black for next loop
        for(int j=0; j<5; j++){
          leds[i+j] = CRGB::Black;
        }
        delay(speed);
      }
    
      // Now go in the other direction.  
      for(int i = NUM_LEDS-width; i >= 0; i--) {
        for(int j=0; j< width; j++){
          leds[i+j] = c;
        }
        FastLED.show();
        for(int j=0; j< width; j++){
          leds[i+j] = CRGB::Black;
        }
    
        delay(speed);
      }
    }
    
    // Display alternating stripes
    void stripes(CRGB c1, CRGB c2, int width){
      for(int i=0; i< NUM_LEDS; i++){
        if(i % (width * 2) < width){
          leds[i] = c1;
        }
        else{
          leds[i] = c2;
        } 
      }
      FastLED.show();
    }
    
    // Theater-style crawling of stripes
    void stripesChase(CRGB c1, CRGB c2, int width, int cycles, int speed){ // TODO direction
    
    }
    
    // Input a value 0 to 255 to get a color value.
    // The colours are a transition r - g - b - back to r.
    CRGB Wheel(byte WheelPos) {
      if(WheelPos < 85) {
        return CRGB(WheelPos * 3, 255 - WheelPos * 3, 0);
      } 
      else if(WheelPos < 170) {
        WheelPos -= 85;
        return CRGB(255 - WheelPos * 3, 0, WheelPos * 3);
      } 
      else {
        WheelPos -= 170;
        return CRGB(0, WheelPos * 3, 255 - WheelPos * 3);
      }
    }
    
    CRGB randomColor(){
      return Wheel(random(256)); 
    }
    
    
                                          
                                    

    Step(3): Programming the ESP 8266 board

    • I used also Eagle to design the schematic and layout.
    • It is important to fix the antenna outside the board so there is noe copper underneath.
    • I made 2 push buttons, one for flashing and one for resetting.
    • Exported the GERBER files and used Gerbv and GIMP to generate the .png images.
    • Fab Modules is a good tool to generate the .Gcode and run the MonoFab SRM-20.
    • I exported 2 .png files, one for milling the traces, one for drilling the holes and the third one for cutting the outline.
    • Soldered the ESP8266 and the other components on the board and connected it with an FTDI cable to the pc.
    • I searched many tutorials about making a webserver on the internet using the ESP8266 and found Web Server with ESP8266


    •                                     
      
      /*********
        Rui Santos
        Complete project details at https://randomnerdtutorials.com  
      *********/
      
      // Load Wi-Fi library
      #include < ESP8266WiFi.h>
      
      // Replace with your network credentials
      const char* ssid     = "Orange-D955";
      const char* password = "IloveFLE";
      
      // Set web server port number to 80
      WiFiServer server(80);
      
      // Variable to store the HTTP request
      String header;
      
      // Auxiliar variables to store the current output state
      String output5State = "off";
      String output4State = "off";
      
      // Assign output variables to GPIO pins
      const int output5 = 5;
      const int output4 = 4;
      
      // Current time
      unsigned long currentTime = millis();
      // Previous time
      unsigned long previousTime = 0; 
      // Define timeout time in milliseconds (example: 2000ms = 2s)
      const long timeoutTime = 2000;
      
      void setup() {
        Serial.begin(115200);
        // Initialize the output variables as outputs
        pinMode(output5, OUTPUT);
        pinMode(output4, OUTPUT);
        // Set outputs to LOW
        digitalWrite(output5, LOW);
        digitalWrite(output4, LOW);
      
        // Connect to Wi-Fi network with SSID and password
        Serial.print("Connecting to ");
        Serial.println(ssid);
        WiFi.begin(ssid, password);
        while (WiFi.status() != WL_CONNECTED) {
          delay(500);
          Serial.print(".");
        }
        // Print local IP address and start web server
        Serial.println("");
        Serial.println("WiFi connected.");
        Serial.println("IP address: ");
        Serial.println(WiFi.localIP());
        server.begin();
      }
      
      void loop(){
        WiFiClient client = server.available();   // Listen for incoming clients
      
        if (client) {                             // If a new client connects,
          Serial.println("New Client.");          // print a message out in the serial port
          String currentLine = "";                // make a String to hold incoming data from the client
          currentTime = millis();
          previousTime = currentTime;
          while (client.connected() && currentTime - previousTime <= timeoutTime) { // loop while the client's connected
            currentTime = millis();         
            if (client.available()) {             // if there's bytes to read from the client,
              char c = client.read();             // read a byte, then
              Serial.write(c);                    // print it out the serial monitor
              header += c;
              if (c == '\n') {                    // if the byte is a newline character
                // if the current line is blank, you got two newline characters in a row.
                // that's the end of the client HTTP request, so send a response:
                if (currentLine.length() == 0) {
                  // HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK)
                  // and a content-type so the client knows what's coming, then a blank line:
                  client.println("HTTP/1.1 200 OK");
                  client.println("Content-type:text/html");
                  client.println("Connection: close");
                  client.println();
                  
                  // turns the GPIOs on and off
                  if (header.indexOf("GET /5/on") >= 0) {
                    Serial.println("GPIO 5 on");
                    output5State = "on";
                    digitalWrite(output5, HIGH);
                  } else if (header.indexOf("GET /5/off") >= 0) {
                    Serial.println("GPIO 5 off");
                    output5State = "off";
                    digitalWrite(output5, LOW);
                  } else if (header.indexOf("GET /4/on") >= 0) {
                    Serial.println("GPIO 4 on");
                    output4State = "on";
                    digitalWrite(output4, HIGH);
                  } else if (header.indexOf("GET /4/off") >= 0) {
                    Serial.println("GPIO 4 off");
                    output4State = "off";
                    digitalWrite(output4, LOW);
                  }
                  
                  // Display the HTML web page
                  client.println("< html>");
                  client.println("< head>< meta name=\"viewport\" content=\ " width=device-width, initial-scale=1\">");
                  client.println("< link rel=\"icon\" href=\"data:,\">");
                  // CSS to style the on/off buttons 
                  // Feel free to change the background-color and font-size attributes to fit your preferences
                  client.println("< style>html { font-family: Helvetica; display: inline-block; margin: 0px auto; text-align: center;}");
                  client.println(".button { background-color: #195B6A; border: none; color: white; padding: 16px 40px;");
                  client.println("text-decoration: none; font-size: 30px; margin: 2px; cursor: pointer;}");
                  client.println(".button2 {background-color: #77878A;}< /style>< /head>");
                  
                  // Web Page Heading
                  client.println("< body>< h1>ESP8266 Web Server");
                  
                  // Display current state, and ON/OFF buttons for GPIO 5  
                  client.println("< p>GPIO 5 - State " + output5State + "< /p>");
                  // If the output5State is off, it displays the ON button       
                  if (output5State=="off") {
                    client.println("< p>< a href=\"/5/on\">< button class=\"button\">ON");
                  } else {
                    client.println("< p>< a href=\"/5/off\">< button class=\"button button2\">OFF< /button>");
                  } 
                     
                  // Display current state, and ON/OFF buttons for GPIO 4  
                  client.println("< p>GPIO 4 - State " + output4State + "");
                  // If the output4State is off, it displays the ON button       
                  if (output4State=="off") {
                    client.println("< p>< a href=\"/4/on\">< button class=\"button\">ON< /button>< /p>");
                  } else {
                    client.println("< p>< a href=\"/4/off\">< button class=\"button button2\">OFF");
                  }
                  client.println("< /body>");
                  
                  // The HTTP response ends with another blank line
                  client.println();
                  // Break out of the while loop
                  break;
                } else { // if you got a newline, then clear currentLine
                  currentLine = "";
                }
              } else if (c != '\r') {  // if you got anything else but a carriage return character,
                currentLine += c;      // add it to the end of the currentLine
              }
            }
          }
          // Clear the header variable
          header = "";
          // Close the connection
          client.stop();
          Serial.println("Client disconnected.");
          Serial.println("");
        }
      }
      
      
                                            
                                      

      Step(3): Identifying the Addressable RGB Leds

    • Parameters:
      • Working Voltage: DC 12V
      • LED Source: SMD 5050 RGB
      • LED Chip: Epistar
      • LED QTY: 60 LED/M
      • IC QTY: 20 Pcs/M
      • Power: 18 W/M
      • Grey Scale: 256 / Color
      • Cutability: 3 led / cutting (External 2811 ic, 1 ic control 3 LED)
      • Color Mode: 133Pattern & 100 Speeds
      • Dimension: 5000mm x 10mm x 2.4mm
    • Features:
      • Flexible PCB With 3M adhesive tape on the back for easy installation.
      • High brightness 5050 SMD LED light strip
      • Low power consumption, high intensity
      • Match the RGB controller and power supplier system.
      Snow
      Forest

      Step(4): Application testing

      • I edited in both codes of the ATMega 328p and the esp8266, the final codes are in the download files.
      • I used the main structure and implemented the rgb leds on its drawers, connected the 2 boards and powered them up.
      • Here is a video showing the interfacing

      Group Assignment

      Introduction

      In this assignment we were supposed to explore as many tool options as possible. So we went with Processing, MIT APP Inventor and Scratch. I will provide an overview for each software and outline its pros and cons.

      Processing

    • Is a very powerful tool that is also commonly used to design interfaces for Arduino and other microcontroller boards. It has a lot of features, and we can easily switch modes within the software to do Java, Python and p5.js programming. Also, it has a lot of community support as well, which makes looking for solutions to problems easier.
    • Is a flexible software sketchbook and a language for learning how to code within the context of the visual arts. Since 2001, Processing has promoted software literacy within the visual arts and visual literacy within technology. There are tens of thousands of students, artists, designers, researchers, and hobbyists who use Processing for learning and prototyping.
    • Advantages:
      • Interactive programs with 2D, 3D, PDF, or SVG output.
      • Free to download and open source.
      • Over 100 libraries extend the core software.
      • For GNU/Linux, Mac OS X, Windows, Android, and ARM.
      • OpenGL integration for accelerated 2D and 3D.
      • Well documented, with many books available
    • Disadvantage:
      • it is a programming language, meaning that it is low level.


      MIT APP Inventor

    • Is an excellent tool for learning mobile development, especially if one is coming from a non-programming background. The drag and drop mechanism is really simple and well thought out, and is quite useful as a teaching tool.
    • is an intuitive, visual programming environment that allows everyone – even children – to build fully functional apps for Android and iOS smartphones and tablets. Those new to MIT App Inventor can have a simple first app up and running in less than 30 minutes. And what's more, our blocks-based tool facilitates the creation of complex, high-impact apps in significantly less time than traditional programming environments. The MIT App Inventor project seeks to democratize software development by empowering all people, especially young people, to move from technology consumption to technology creation.
    • Advantages:
      • Visual programming language with puzzle pieces.
      • Access to most of the phone's functionality: phone calls, SMS texting, sensors for location, orientation, and acceleration, text-to-speech and speech recognition, sound, video.
      • The ability to invoke other apps, with the ActivityStarter component.
      • Programming control just as with a textual language. There are blocks for conditionals (if, ifelse), foreach, and while, and a fairly comprehensive list of math and logic blocks.
      • Database access, both on the device and on the web. So you can save data persistently, and with a web database share data amongst phones.
      • Access to web information sources (APIs)-- you can bring in data from Facebook, Amazon, etc. See limitations below.
    • Limitations:
      • Limited UIs: The user interface builder has improved but is still a bit buggy and limited, so you can't build any user interface. For instance, you can't create apps with multiple screens and handling orientation changes has some glitches. These problems are not fundamental to the design of App Inventor and will soon be fixed.
      • Limited Access to the device: There are not yet components for all the data and functionality of the phone. For instance, you can't save and retrieve files from the file system and you have only limited access to the contact list (e.g., you cannot create groups).
      • Limited Access to Web: You can only access APIs that follow a particular prototocol (App-Inventor-compatible APIs). So if you want to get data from the web, you'll need to program or have a programmer create an App-Inventor-Compliant API that wraps an existing API.
      • Limited access to the Android Market: The apps (.apk files) generated by App Inventor lack the required configuration for direct inclusion in the market. However, there is now a workaround for market publication.
      • No polymorphic components: Function blocks are tied to specific components, so there is no way to call functions on a generic component. For instance, if you create a procedure MoveXY, it has to be tied to a specific image sprite, not a general image sprite.


      Scratch

    • Is an interactive, drag-and-drop programming language that allows users to make animations and games. It’s perfect for beginners, as it helps them understand the logic of programming without needing any prior knowledge! The knowledge gained in Scratch can then be applied to real programming languages.
    • is an intuitive, visual programming environment that allows everyone – even children – to build fully functional apps for Android and iOS smartphones and tablets. Those new to MIT App Inventor can have a simple first app up and running in less than 30 minutes. And what's more, our blocks-based tool facilitates the creation of complex, high-impact apps in significantly less time than traditional programming environments. The MIT App Inventor project seeks to democratize software development by empowering all people, especially young people, to move from technology consumption to technology creation.
    • Pros:
      • Easy to use interface: the interface is very easy to use. You can drag and drop various ‘blocks’, categorised as motion, looks, sound, etc. Definitely easy enough for a 10 year old kid to use.
      • Online version: Scratch can be used online without downloading. What is more, you can download and upload your work from and to the website, so students need not make an account to save their work. Again, this is good for using in a school environment where installing software may not be possible, and eliminating the need to make an account is useful for students – no need to remember passwords, etc.
      • Fun: Scratch can be used to make very fun projects that spark one’s interest, especially when teaching to children. Having fun is the best way to learn. For example, some of the projects I have taught students to build were a space animation, a band, and a game with balloons.
    • Cons:
      • Closed source: Scratch is, unfortunately, closed source. This is a huge pity, given that it’s supposed to be about learning and sharing, but its creators seem to have no interest in helping others learn from their work. If it were open source, people could adapt it to their needs, contribute features, and learn from its code!
      • The colour scheme: Few colours look very similar: Motion and Looks (and to some extend, sound), as well as Data, Events, and Control are nearly identical. This problem becomes worse if you’re colour-blind. But what’s even worse is that these colours look almost identical when looked at from an interactive board, especially from a distance. This confuses my students because they keep looking in the wrong categories. This may be a problem with the interactive board, but they should have made more of an attempt to make the colours look different, since interactive boards are very common in classrooms.


      Up & Running with Processing

      Overview

    • We designed and fabricated a board for interfacing using processing, the board is a led matrix connected to a microcontroller using a charlieplexing technique which allows you to control a big number of LEDs using a small number of output pins. In our case we use 3 pins to control 6 LEDs
    • We have designed the PCB on Autodesk Eagle which includes the essential components to make this board working. The PCB includes an embedded microcontroller, a programming port to upload your code on the microcontroller, 6 LEDs and their resistors and finally a FTDI port to communicate with the PC later on.



    • Programming with Arduino IDE

                                          
      //
      //
      // hello.array.44.c
      //
      // Charlieplex LED array hello-world
      //
      // Neil Gershenfeld
      // 11/13/10
      //
      // (c) Massachusetts Institute of Technology 2010
      // This work may be reproduced, modified, distributed,
      // performed, and displayed for any purpose. Copyright is
      // retained and must be preserved. The work is provided
      // as is; no warranty is provided, and users accept all 
      // liability.
      //
      
      #include 
      #include 
      
      #define output(directions,pin) (directions |= pin) // set port direction for output
      #define input(directions,pin) (directions &= (~pin)) // set port direction for input 
      #define set(port,pin) (port |= pin) // set port pin
      #define clear(port,pin) (port &= (~pin)) // clear port pin
      #define pin_test(pins,pin) (pins & pin) // test for port pin
      #define bit_test(byte,bit) (byte & (1 << bit)) // test for bit set
      
      #define bit_delay_time 102 // bit delay for 9600 with overhead
      #define bit_delay() _delay_us(bit_delay_time) // RS232 bit delay
      #define half_bit_delay() _delay_us(bit_delay_time/2) // RS232 half bit delay
      
      
      #define led_delay() _delay_ms(1) // LED delay
      
      #define flash_delay 1
      
      #define led_port PORTB
      #define led_direction DDRB
      
      #define C (1 << PB0) // row 1
      #define B (1 << PB1) // row 2
      #define A (1 << PB2) // row 3
      
      #define serial_port PORTB
      #define serial_direction DDRB
      #define serial_pins PINB
      #define serial_pin_in (1 << PB3)
      
      void get_char(volatile unsigned char *pins, unsigned char pin, char *rxbyte) {
         //
         // read character into rxbyte on pins pin
         //    assumes line driver (inverts bits)
         //
         *rxbyte = 0;
         while (pin_test(*pins,pin))
            //
            // wait for start bit
            //
            ;
         //
         // delay to middle of first data bit
         //
         half_bit_delay();
         bit_delay();
         //
         // unrolled loop to read data bits
         //
         if pin_test(*pins,pin)
            *rxbyte |= (1 << 0);
         else
            *rxbyte |= (0 << 0);
         bit_delay();
         if pin_test(*pins,pin)
            *rxbyte |= (1 << 1);
         else
            *rxbyte |= (0 << 1);
         bit_delay();
         if pin_test(*pins,pin)
            *rxbyte |= (1 << 2);
         else
            *rxbyte |= (0 << 2);
         bit_delay();
         if pin_test(*pins,pin)
            *rxbyte |= (1 << 3);
         else
            *rxbyte |= (0 << 3);
         bit_delay();
         if pin_test(*pins,pin)
            *rxbyte |= (1 << 4);
         else
            *rxbyte |= (0 << 4);
         bit_delay();
         if pin_test(*pins,pin)
            *rxbyte |= (1 << 5);
         else
            *rxbyte |= (0 << 5);
         bit_delay();
         if pin_test(*pins,pin)
            *rxbyte |= (1 << 6);
         else
            *rxbyte |= (0 << 6);
         bit_delay();
         if pin_test(*pins,pin)
            *rxbyte |= (1 << 7);
         else
            *rxbyte |= (0 << 7);
         //
         // wait for stop bit
         //
         bit_delay();
         half_bit_delay();
         }
      
      
      
      void flash(uint8_t from, uint8_t to, uint8_t delay) {
         //
         // source from, sink to, flash
         //
         static uint8_t i;
         set(led_port,from);
         clear(led_port,to);
         output(led_direction,from);
         output(led_direction,to);
         for (i = 0; i < delay; ++i)
             led_delay();
         input(led_direction,from);
         input(led_direction,to);
         }
      
      void led_cycle_CCW(uint8_t number, uint8_t delay) {
         //
         // cycle through LEDs
         //
         uint8_t i;
         for (i = 0; i < number; ++i) {
            flash(A,B,delay);
            flash(A,C,delay);
            flash(B,A,delay);
            flash(B,C,delay);
            flash(C,A,delay);
            flash(C,B,delay);
            }
         }
      void led_cycle_CW(uint8_t number, uint8_t delay) {
         //
         // cycle through LEDs
         //
         uint8_t i;
         for (i = 0; i < number; ++i) {
            flash(C,B,delay);
            flash(B,C,delay);
            flash(B,A,delay);
            flash(C,A,delay);
            flash(A,C,delay);
            flash(A,B,delay);
            }
         }
      
      void flash_all(uint8_t number)
      {
         for (int i = 0; i < number; ++i)
         {
            flash(A, B, flash_delay);
            flash(A, C, flash_delay);
            flash(B, A, flash_delay);
            flash(B, C, flash_delay);
            flash(C, A, flash_delay);
            flash(C, B, flash_delay);
         }
      }
      void dance(void)
      {
         led_cycle_CCW(10, 50);
         flash_all(100);
         led_cycle_CW(10, 50);
         flash_all(100);
      }
      
      void flash_pattern(uint8_t pattern, uint8_t number)
      {
         for (int i = 0; i < number; ++i)
         {
            if((pattern >> 1) & (1))
               flash(A, B, flash_delay);
            if((pattern >> 2) & (1))
               flash(A, C, flash_delay);
      
            if((pattern >> 3) & (1))
               flash(B, A, flash_delay);
            if((pattern >> 4) & (1))
               flash(B, C, flash_delay);
      
            if((pattern >> 5) & (1))
               flash(C, A, flash_delay);
            if((pattern >> 6) & (1))
               flash(C, B, flash_delay);
         }
      }
      
      static char chr;
      
      void setup()
      {
         //
         // set clock divider to /1
         //
         CLKPR = (1 << CLKPCE);
         CLKPR = (0 << CLKPS3) | (0 << CLKPS2) | (0 << CLKPS1) | (0 << CLKPS0);
        
      }
      
      void loop()
      {
           // dance();
      
            // comment above line and uncomment below lines for demo 2
           get_char(&serial_pins,serial_pin_in,&chr);
           flash_pattern(chr, 2000);
      }
      
                                            
                                      

      Snow
      Forest
      Forest
      Forest

      Processing Code

                                          
      
      import processing.serial.*;
      
      Serial myserial;
      
      int data = 0;
      
      boolean led_1 = false;
      boolean led_2 = false;
      boolean led_3 = false;
      boolean led_4 = false;
      boolean led_5 = false;
      boolean led_6 = false;
      
      int bit_1 = 0;
      int bit_2 = 0;
      int bit_3 = 0;
      int bit_4 = 0;
      int bit_5 = 0;
      int bit_6 = 0;
      
      int offsetx = 150;
      int offsety = 125;
      int x1 = 50;
      int y1 = 50;
      
      int x2 = x1 + offsetx;
      int y2 = y1;
      
      int x3 = x2 + offsetx;
      int y3 = y2;
      
      int x4 = 50;
      int y4 = y1 + offsety;
      
      int x5 = x4 + offsetx;
      int y5 = y4;
      
      int x6 = x5 + offsetx;
      int y6 = y5;
      
      int x7 = x5;
      int y7 = y6 + offsety;
      
      int w = 100;
      int h = 75;
      
      void setup() {
        size(500, 400); 
        
        String myPort = Serial.list()[1];
        
        myserial = new Serial(this, myPort, 9600);
      }
      
      void draw() {
        if (led_1) 
        {
          fill(255);
          rect(x1,y1,w,h);
        } 
        else 
        {
          fill(100);
          rect(x1,y1,w,h);
        }
        
        if (led_2) 
        {
          fill(255);
          rect(x4,y4,w,h);
        } 
        else 
        {
          fill(100);
          rect(x4,y4,w,h);
        }
        
        if (led_3) 
        {
          fill(255);
          rect(x2,y2,w,h);
        } 
        else 
        {
          fill(100);
          rect(x2,y2,w,h);
        }  
      
      
        if (led_4) 
        {
          fill(255);
          rect(x5,y5,w,h);
        } 
        else 
        {
          fill(100);
          rect(x5,y5,w,h);
        }
      
        if (led_5) 
        {
          fill(255);
          rect(x3,y3,w,h);
        } 
        else 
        {
          fill(100);
          rect(x3,y3,w,h);
        }
        
        if (led_6) 
        {
          fill(255);
          rect(x6,y6,w,h);
        } 
        else 
        {
          fill(100);
          rect(x6,y6,w,h);
        }
        
        fill(50);
        rect(x7, y7, w, h);
      
      }
      
      // When the mouse is pressed, the state of the button is toggled.
      void mousePressed() {
        if (mouseX > x1 && mouseX < x1+w && mouseY > y1 && mouseY < y1+h) {
          led_1 = !led_1;
          bit_1 = bit_1 ^ 1;
        } 
      
        if (mouseX > x2 && mouseX < x2+w && mouseY > y2 && mouseY < y2+h) {
          led_3 = !led_3;
          bit_3 = bit_3 ^ 1;
        }  
      
        if (mouseX > x3 && mouseX < x3+w && mouseY > y3 && mouseY < y3+h) {
          led_5 = !led_5;
          bit_5 = bit_5 ^ 1;
      
      }  
        
        if (mouseX > x4 && mouseX < x4+w && mouseY > y4 && mouseY < y4+h) {
          led_2 = !led_2;
          bit_2 = bit_2 ^ 1;
      
      }  
        
        if (mouseX > x5 && mouseX < x5+w && mouseY > y5 && mouseY < y5+h) {
          led_4 = !led_4;
          bit_4 = bit_4 ^ 1;
      
      }  
        
        if (mouseX > x6 && mouseX < x6+w && mouseY > y6 && mouseY < y6+h) {
          led_6 = !led_6;
          bit_6 = bit_6 ^ 1;
      
      }  
      
      
      
        if (mouseX > x7 && mouseX < x7+w && mouseY > y7 && mouseY < y7+h) {
          data = bit_6<<6 | bit_5<<5 | bit_4<<4 | bit_3<<3 | bit_2<<2 | bit_1<<1;
          myserial.write(data);
        }
        
      
      }
      
                                            
                                      

      Running Processing

      Snow
      Forest

      Downloads:

      Downloads(Design files+Source codes).rar Group Assignment (PCB Files + Arduino Code + Processing Code).rar