Robotic Power System Activity Guide

From STEAMwiki
Jump to: navigation, search

Power model.jpg

Introduction

The Power System activity is designed to help teachers bring high tech making into the classroom. This is a multi-day activity, and consists of building a physical model of Ontario's electricity system together! It will have models of each kind of electricity generation type: nuclear, wind, hydro-electric, etc. We'll bring craft materials, and you will ask the kids ahead of time to bring in recycled materials.

Electric motors will also be added to the power generation plants to show rotating wind turbines, hydroelectric generator turbines and anything else the kids come up with. Video of a this robotic power system model's motors in action.

In addition, the physical model will be interactive, with a web page acting as a remote control. This web page pulls power generation data from Ontario's power producers to show a live chart of how our power is being generated. Buttons allow the user to browse previous days' power generation data to see how this changes over time. Live power generation data. Link to live demo.

The power generation data is also sent to the model itself. A grid of 60 LEDs light up proportionally to the current power generation information.

LED display of power data

CIRA Logo.png This activity was designed with Ontario's power system in mind, but can easily be adapted for any other location.

This material was developed with funding from the Canadian Internet Registration Authority’s (CIRA) Community Investment Program.

Technology Skills Required

There are 4 core technology skills required to run this activity. If you, the teacher, don't have these skills, you have 2 options - learn or find a technologist to partner with.

With the resource links below, you will be able to teach yourself all the skills you need. It's becoming easier and easier to learn these skills with the tools themselves getting easier to use, and with more advanced teaching tools.

If you don't have the time or inclination to learn these skills, find someone in your community that does! These technology topics are very popular, and you should be able to find someone in your network or parents and colleagues interested in helping.

  1. Basic electrical circuits
    Sparkfun - What is a Circuit?
  2. Arduino coding
    The STEAMLabs Internet of Things teaching kit has progressive code examples to teach you all the skills you need for this activity. It's designed for a non-technical audience to get you started from the beginning.
    The [Coding Resources] section of this wiki also has material for learning Arduino and the specialized Particle Internet of Things extensions.
  3. HTML & CSS
    Mozilla's Introduction to HTML
    Mozilla's Learning CSS Modules
    STEAMLabs HTML & CSS Teaching Slides
  4. 3D Design and printing
    STEAMLabs 3D Printing activity guide


Curriculum Connections

This activity has many specific connections to the Ontario grade 6 curriculum. This makes it easier to dedicate the classroom time to it, since progress is being made on this curriculum.

Science

The Ontario grade 6 science curriculum is available online here: http://www.edu.gov.on.ca/eng/curriculum/elementary/scientec18currb.pdf

Core concepts of the Electricity unit covered:

  • Electrical energy can be transformed into other forms of energy.
  • Other forms of energy can be transformed into electrical energy.
  • Electrical energy plays a significant role in society, and its production has an impact on the environment.
  • Society must find ways to minimize the impact of energy production on the environment.

Math

The Ontario grade 6 math curriculum is available online here: http://www.edu.gov.on.ca/eng/curriculum/elementary/math18curr.pdf

Core concepts covered:

  • Problem solving
  • Fractions and percentages
  • Collection and Organization of Data
  • Representations of mathematical ideas

Art

The Ontario grade 6 art curriculum is available online here: http://www.edu.gov.on.ca/eng/curriculum/elementary/arts18b09curr.pdf

Core concepts covered:

  • Creating and Presenting
  • Reflecting, Responding, and Analysing
  • Exploring Forms and Cultural Contexts

Materials

Parts and materials to obtain:

Equipment

  • Computer(s)
  • Soldering iron and soldering supplies
  • 3D Printer

For the 3D printer, we recommend Ultimaker or Printrbot. Both companies make very good quality printers, consistently scoring near the top in Make Magazine's 3D Printer tests. Ultimaker is more expensive, but is also easier to use and maintain.

Electronics

The Particle Photon does not put out enough electrical current to directly power the motors. The motor driver board is required to amplify the Particle's output and power the motor(s).

Craft supplies

  • Glue guns
  • Recycled materials such as cardboard tubes, boxes, plastic cases
  • Craft foam for colour details
  • Foamcore sheet for the base
  • Duct tape
  • Any other craft materials you like!

Preparation

In addition to ordering the materials, you must also plan for the sessions.

Seek out a way to present the power system model when it is complete. This gives the kids a purpose - they are going to actually use the model to teach people about our power system.


Session 1

The goals of the first session are to introduce the concept to get the kids thinking about the power system, and to introduce them to the technologies that they will use to build their model. You should also use this session to gauge their interest and existing skills with the technologies. Each session is designed to be approximately a half day each.

Introduce concept

Start with telling the kids that they are all science centre exhibit designers! This is a real project to teach science to kids and adults. The first step is to start a discussion about what makes a good exhibit. Guide them towards these key points:

  1. Information
  2. Interaction
  3. Fun!

Next, dissect some existing exhibits that they have seen in science centres and museums. Start a google document to add information about their favourites, keeping in mind the three points above. Have them work in groups adding this information about each one:

  • Find a picture of the exhibit
  • What does it teach you?
  • List the good things about the exhibit

This google doc will be useful for assessing the students understanding later.

Power System Research

Now that they have a good idea about what makes a good exhibit, in order to plan their own, the students need to know more about the power system itself.

As much as possible, have the kids teach each other this section! They will collectively know a fair amount about the system, so teach them by asking them questions. When they are stuck, or wrong, fill in the gaps with your own knowledge, or by researching online together. This will get them in the habit of learning for themselves. The sections below contain resources to bring up on a video display if you have one, so that you can use them as research and visual aids.

Power Producers

Where does our power come from?

Tell the students that there are 4 main ways our power is generated, and a bunch of smaller ways. Their job is to identify at the very least the 4 main ways, and as many of the smaller ways as they can. As they come up with ideas, write them on the board. Usually they will come up with some related technologies that aren't quite what you meant. Run with it, and explain how that fits in! For example, a student might say "Turbines". Turbines are used as a part of many the systems for generating power! Water flowing through hydroelectric dams turns a turbine, which turns a generator to make power.

Main power producers:

  1. Nuclear
  2. Hydroelectric
  3. Natural Gas
  4. Wind

Secondary power producers:

  1. Solar
  2. Biomass
  3. Diesel

No longer used in Ontario:

  1. Coal

Resources for power supply information:

Live production data: https://cns-snc.ca/media/ontarioelectricity/ontarioelectricity.html

Power supply history: http://www.ieso.ca/Pages/Power-Data/Supply.aspx

Once the power producers are identified, it's time to make groups! Make sure there are people who want to make the main 4, and as many as are interested in the Balance the groups so that an approximately even number of students is in each.

Each group will research their power producer and make the physical model of it. In this session, they will start writing the description and research notes in a Google doc. This will be transferred to a web page next week. They should also draw a plan of what the model looks like.

Have them start off their Google doc with these questions to answer. Create the questions as a group - have them figure out what is important to know.

  1. How does this power generation method work?
  2. What are its advantages?
  3. What are its disadvantages?
  4. How does it affect the environment?
  5. How expensive is this method of power generation compared to other methods?
  6. Are there any seasonal or time of day changes to this power generation method? How will we cope with these changes?
  7. Any other questions relevant to their power generation system.

Power Consumers

Where does our power go?

The next step is to identify what we use power for. Following a similar process, the class will identify the main types of power consumers:

Main power consumers:

  1. Residential (Homes)
  2. Commercial (Offices, schools, stores, etc)
  3. Industrial (Factories, mines, etc)
  4. Agriculture
  5. Transportation

Any other examples that the students come up with of power consumers should be consolidated into these main groups. Once these 5 have been identified, show them the mix of the use percentage of each type from the Natural Resources Canada Energy Fact Book 2015 page 86 https://www.nrcan.gc.ca/sites/www.nrcan.gc.ca/files/energy/files/pdf/EnergyFactBook2015-Eng_Web.pdf

Next, tell them that our model will contain miniature 3D printed models of these power consumers. We'll have room for 60 of them on the model, so how many from each sector should we include? Guide them towards the answer that they should be proportional to the amount of power that each sector uses. If one sector uses more power than another, there should be more of those model buildings.

Power system houses.jpg

Using percentages, have them calculate how many models should be 3D printed of each category. Adjust the numbers to make sure they add up to 60, since they may not due to rounding errors. For example:

Sector Energy use (PJ) % of the total Number of models
Residential 543.3 29.7% 18
Commercial 532.8 29.2% 17
Industrial 714.2 39.1% 23
Transportation 3.8 0.2% 1
Agriculture 33.0 1.8% 1
Total 1,827.2 100% 60


Introduce technology

The next section is designed to expose the students to the technology that will be available to them to build their exhibit. This first session will give them a chance to play with the tech, and see what appeals to them. Later, they will be split into teams based on this interest to learn more and to build specific parts of the model.

Three technology activity stations will be set up, and the kids will have the opportunity to try all three, depending on their interests.

3D Printing

All the kids will start with this station, and learn to 3D print. The final power system model will have small 3D printed models of the power consumers - residences, offices, factories, etc. They can each design and print their own buildings. Just make sure that the small consumer categories such as Agriculture and Transportation only have one building, since that is all that is needed.

Use TinkerCad.com, a free online 3D design tool to make the buildings. Use our [3D Printing activity guide] to teach this topic.

Power system factory.png

Electronics

Neopixel LED strip programming

The electronics station is meant to get the kids excited about the capabilities of the Neopixel strip and motors. Rather than teach them step by step Arduino coding, you will set up some pre-existing code and challenge them to modify it. The kids that are interested in coding can use this as a starting point to learn more about Arduino.

Set up the Neopixel strip to a particle Photon chip. Connect the data pin on the Neopixel strip to the D2 pin on the Photon, the power to VIN since the Neopixels need 5v.

Connect 2 geared motors to the Photon, with motor drivers. Connect one motor to be activated by pin D4, and one by pin D5. Explain that these motors can be used in the model to activate different aspects of their models. For an example, show them this video of a this robotic power system model.

Load the code below on to the Particle Photon. You must also include the Neopixel library into the app, using the "Libraries" tab in the Particle web IDE.

Give the kids at the station these challenges:

  1. Change the colours of the LEDs
  2. Make some more LEDs light up
  3. Make the second motor turn on
#include "neopixel/neopixel.h"
#include "application.h"

// IMPORTANT: Set pixel COUNT, PIN and TYPE
#define PIXEL_PIN D2
#define PIXEL_COUNT 60
#define PIXEL_TYPE WS2812B

Adafruit_NeoPixel strip = Adafruit_NeoPixel(PIXEL_COUNT, PIXEL_PIN, PIXEL_TYPE);

void setup() 
{
  strip.begin();
  strip.show(); // Initialize all pixels to 'off'
  pinMode(D4, OUTPUT);
  pinMode(D5, OUTPUT);
}

void loop() 
{
    // Instructions:
    // strip.setPixelColor(pixelNumber, red, green, blue);
    
    strip.setPixelColor(1, 255, 0, 255);
    strip.setPixelColor(2, 0, 126, 255);
    strip.setPixelColor(3, 127, 127, 255);
    strip.setPixelColor(4, 255, 0, 0);
    strip.setPixelColor(5, 255, 127, 0);
    strip.setPixelColor(6, 255, 127, 0);
    strip.show();
    
    // Motors on / off:
    digitalWrite(D4, HIGH);
    digitalWrite(D5, LOW);
    delay(1000);
    
    strip.setPixelColor(1, 0, 0, 255);
    strip.setPixelColor(2, 255, 255, 255);
    strip.setPixelColor(3, 0, 0, 255);
    strip.setPixelColor(4, 127, 0, 255);
    strip.setPixelColor(5, 255, 127, 255);
    strip.setPixelColor(6, 255, 129, 255);
    strip.show();

    // Motors off / off:
    digitalWrite(D4, LOW);
    digitalWrite(D5, LOW);
    delay(1000);
}


Web Coding

At this station, students will experiment with an HTML page to learn a bit about how the web works. Set up one or more computers with Mozilla Thimble:

https://thimble.mozilla.org

The idea isn't to teach them web coding yet, just give them a chance to explore. Teaching web technology will happen in the next session.

Session 2

The goals of the second session are to:

  1. Learn web coding
  2. Plan the overall physical model
  3. Get them started building their power plants

In between Session 2 and 3, they should work on the physical models.

Web Coding

Find the kids that are interested in being a part of the "HTML Team". Make sure there is at least one from each power plant group, so that they can convert their group's Google doc with the information about their power plant into an HTML page. Use the STEAMLabs HTML & CSS Teaching Slides to teach web coding.

Have each of them work in Mozilla Thimble to create their group's information page: https://thimble.mozilla.org

Build the models

Natural Gas Plant

Have the kids bring in any recycled and craft materials that they can from home. Give each group a geared motor and a battery pack to power it to let them work this in to their design.

Session 3

Build week! In this session, the models are finished off, and connected to the Particle Photon chip.

Particle Arduino Code

It's time to connect the motors from the physical models to the Particle Photon chip! Connect motor drivers so that pins D4, D5, D6 and D7 control 4 different motors in the model.

The 60 LED Neopixel strip should be connected to pin D2. Place the 3D printed power consumers on the Neopixel strip. 3D print them in clear filament so that the Neopixels shine through. They will light up with the live data with the current power generation mix.

// This #include statement was automatically added by the Spark IDE.
#include "neopixel/neopixel.h"

#include "application.h"
//#include "spark_disable_wlan.h" // For faster local debugging only

#define PIXEL_PIN D2
#define PIXEL_COUNT 150
#define PIXEL_TYPE WS2812B

Adafruit_NeoPixel strip = Adafruit_NeoPixel(PIXEL_COUNT, PIXEL_PIN, PIXEL_TYPE);

// IMPORTANT: To reduce NeoPixel burnout risk, add 1000 uF capacitor across
// pixel power leads, add 300 - 500 Ohm resistor on first pixel's data input
// and minimize distance between Arduino and first pixel.  Avoid connecting
// on a live circuit...if you must, connect GND first.

// How many pulses are visible down the strip at once
#define shipPulseSegments 3
#define shipPulsePixelCount 60
int pixelsPerPulse = shipPulsePixelCount/shipPulseSegments;
int shipPulseColour[shipPulseSegments+1];
float shipPulseOpacity[shipPulseSegments+1];
int shipPulseStep = 0;

// 0 = pixel pulses. 1 = pixel display
int pixelMode = 0;

int motorDelays[] = {0,0,0,0};
int motorPins[] = {D4,D5,D6,D7};

void setup() {
  // Serial.begin(9600);
    Spark.function("pixelPulse", pixelPulse);
    Spark.function("pixelDisplay", pixelDisplay);
    Spark.function("motorOn", motorOn);
    
    for (int i=0; i < 4; i++){
        pinMode(motorPins[i], OUTPUT);
    }
    
    
    for (int i = 0; i <= shipPulseSegments; i++) {
        shipPulseColour[i] = 0;
        shipPulseOpacity[i] = 0.0;
    }  
    strip.begin();
    strip.show(); // Initialize all pixels to 'off'
    
    // Default show pixels
    pixelDisplay("39031404");
    
    for (int i = 120; i < 127; i++) {
	    strip.setPixelColor(i, 0, 0, 255);
	}

    for (int i = 127; i < 132; i++) {
	    strip.setPixelColor(i, 255, 0, 0);
	}

    for (int i = 132; i < 137; i++) {
	    strip.setPixelColor(i, 0, 255, 0);
	}

    for (int i = 137; i < 143; i++) {
	    strip.setPixelColor(i, 255, 255, 0);
	}

    
}

void loop () {
    
    if (pixelMode == 0) {
        shipPulse();
    } 
    strip.show();
    motorUpdate();
    delay(20);
}



void shipPulse() {
  for (int i = 0; i < shipPulseSegments+1; i++) {
    // Each segment. Build one extra segment off to the left, since they are shifted off the end

    for (int f = 0; f <  pixelsPerPulse; f++) {
      int pulsePixelIndex = (i-1)*pixelsPerPulse + f + shipPulseStep;
      if (pulsePixelIndex >= 0 && pulsePixelIndex < shipPulsePixelCount) {
        // don't bother with the pixels that have left out the side
        // Each pixel within a segment

        if (shipPulseColour[i] == 0) {
          // Black pixel
            strip.setPixelColor(pulsePixelIndex, strip.Color(0,0,0));
        } 
        else {
          // Fade the pixel out as it get further away from the brightest one
          
          float pixelOpacity = float(f) / float(pixelsPerPulse) * float(f) / float(pixelsPerPulse) * float(f) / float(pixelsPerPulse) * shipPulseOpacity[i];
          uint32_t thisPulsePixel = Wheel(shipPulseColour[i], pixelOpacity);
          
          strip.setPixelColor(pulsePixelIndex, thisPulsePixel);
          
        }
      }
    }
  }

  shipPulseStep++;
  if (shipPulseStep > pixelsPerPulse) {

    // Push the existing colours down one
    int oldColour = shipPulseColour[shipPulseSegments-1];
    float oldOpacity = shipPulseOpacity[shipPulseSegments-1];

    for (int i = shipPulseSegments; i > 0; i--) {
      shipPulseColour[i] = shipPulseColour[i-1];
      shipPulseOpacity[i] = shipPulseOpacity[i-1];
    }  

    // Fade out old colours
    if (oldColour > 0) {
      Serial.println(oldOpacity);
    }

    if (oldOpacity > 0.1) {
      // loop - repeat the same colour
      /*
      shipPulseColour[0] = oldColour;
      shipPulseOpacity[0] = oldOpacity * 0.3;
      */
      
      // Disable looping
      shipPulseOpacity[0] = 0;
    } 
    else {

      // Randomize what to do next
      int nextAction = random(3);
      
      // Never make a new pulse, since this is now triggered by the function pixelPulse()
      //int nextAction = 2;
      
      // Serial.println(nextAction);
      
     
      if (nextAction == 0) {
        // Add a new colour
        int newPosition = random(shipPulseSegments);
        int newColour = random(256);
        shipPulseColour[newPosition] = newColour;
        shipPulseOpacity[newPosition] = 1.0;
      } 
      else {
        // Set to black
        shipPulseColour[0] = 0;
        shipPulseOpacity[0] = 0.0;
      }
    }

    shipPulseStep = 0;
    //Serial.println(shipPulseStep); 
  }
}

int pixelPulse(String command) {
    pixelMode = 0;
    
	// Add a new colour
    int newPosition = 0;
    int newColour = random(256);
    if (command == "red") {
        newColour = 85;
    } else if (command == "orange") {
        newColour = 63;
    } else if (command == "yellow") {
        newColour = 42;
    } else if (command == "cyan") {
        newColour = 212;
    } else if (command == "green") {
        newColour = 255;
    } else if (command == "blue") {
        newColour = 170;
    } else if (command == "violet") {
        newColour = 227;
    }
    
    shipPulseColour[newPosition] = newColour;
    shipPulseOpacity[newPosition] = 1.0;
    return 1;
}

int pixelDisplay(String command) {
    
    // Set pixelMode = 1 to disable the pulses during the display
	pixelMode = 0;
	
	int blueCount   = command.substring(0, 2).toInt();
	int redCount    = command.substring(2, 4).toInt();
	int orangeCount = command.substring(4, 6).toInt();
	int greenCount  = command.substring(6, 8).toInt();
	
	int firstDisplayPixel = 60;
	int pixelCount = firstDisplayPixel;

	for (int i = 0; i < blueCount; i++) {
	    strip.setPixelColor(pixelCount, 0, 0, 255);
	    pixelCount++;
	}
	for (int i = 0; i < redCount; i++) {
	    strip.setPixelColor(pixelCount, 255, 0, 0);
	    pixelCount++;
	}
	for (int i = 0; i < orangeCount; i++) {
	    strip.setPixelColor(pixelCount, 255, 180, 0);
	    pixelCount++;
	}
	for (int i = 0; i < greenCount; i++) {
	    strip.setPixelColor(pixelCount, 0, 255, 0);
	    pixelCount++;
	}
	return 1;
}

int motorOn(String command) {
    int motorPin = D5;
    
    if (command == "0") {
        motorPin = D4;
        motorDelays[0] = millis() + 5000;
        
    } else if (command == "1") {
        motorPin = D5;
        motorDelays[1] = millis() + 5000;
    } else if (command == "2") {
        motorPin = D6;
        motorDelays[2] = millis() + 5000;
    } else if (command == "3") {
        motorPin = D7;
        motorDelays[3] = millis() + 5000;
    }
        
    digitalWrite(motorPin, HIGH);
}

int motorUpdate() {
    for (int i=0; i < 4; i++){
        if (motorDelays[i] != 0) {
            if (motorDelays[i] < millis()) {
                digitalWrite(motorPins[i], LOW);
                motorDelays[i] = 0;
            }
        }
    }
}


// Input a value 0 to 255 to get a color value.
// The colours are a transition r - g - b - back to r.
uint32_t Wheel(byte WheelPos, float opacity) {

  if(WheelPos < 85) {
    return strip.Color((WheelPos * 3) * opacity, (255 - WheelPos * 3) * opacity, 0);
  } 
  else if(WheelPos < 170) {
    WheelPos -= 85;
    return strip.Color((255 - WheelPos * 3) * opacity, 0, (WheelPos * 3) * opacity);
  } 
  else {
    WheelPos -= 170;
    return strip.Color(0, (WheelPos * 3) * opacity, (255 - WheelPos * 3) * opacity);
  }
}


Power Graph and Web Remote Control

Start with this code to show the power generation graphs and the motor activation buttons. You can also remix this project here: https://thimbleprojects.org/dimentians/83149

Copy and paste the HTML from each power generation group into this main HTML page.

<!doctype html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Robotic Power System</title>
    <link rel="stylesheet" href="style.css">
    <script src="https://code.jquery.com/jquery-1.11.2.min.js"></script>
    <script src="https://andyforest.github.io/sparkControl/js/sparkControl.js"></script>
    <script src="https://www.google.com/jsapi"></script>
    <script src="https://www.dimentians.com/power/powerGeneration.js"></script>
    
    
    <script type="text/javascript">
      var sparkCore = new sparkControl("Your Device ID Here", "Your Access Token here");
    </script>
  </head>
  
  <body>
    
    <p>
      <button onclick="loadPowerData();">Today's Power</button>
      <button onclick="loadPowerData(1);">Yesterday's Power</button>
      <button onclick="loadPowerData(7);">Last Week's Power</button>
      <button onclick="loadPowerData(30);">Last Month's Power</button>
      <button onclick="loadPowerData(60);">2 Months Ago Power</button>
    </p>
    
    <p>
      <button onclick="nextDayPower(1);">Back 1 Day</button>
      <button onclick="nextDayPower(-1);">Forward 1 Day</button>
    </p>
   
    

    
    <h3 class="ui-state-default ui-corner-all">Power Generation Charts</h3>
    <div id="powerBarchart" style="width: 50%; height: 400px;  float: left"></div>
    
 	<div id="powerPiechart" style="width: 50%; height: 400px; float: left"></div>
    
    <p style="clear: both;">
     Turn on power plant motors:
    
      <button onclick="sparkCore.callFunction('motorOn', '0');">Nuclear</button>
      <button onclick="sparkCore.callFunction('motorOn', '1');">Wind</button>
      <button onclick="sparkCore.callFunction('motorOn', '2');">Gas</button>
      <button onclick="sparkCore.callFunction('motorOn', '3');">Hydro</button>
    </p>
  
    
 
  </body>
   
</html>