Interface and Application Programming: HEAT PATTERN
Week 12 | How to Make (Almost) Anything | MIT Media Lab | Fall 2016
At the beginning of this week I made my new input device for my final project- a grid of heat sensors that captures a 2D temperature pattern. See Final Project for more detail of making the board and references. And then I used processing to start visualizing the gradient heat.
In theory each sensor on this one-wire bus has its own identity and the correct way of find out this information should be connect them individually and run a address finder program using Arduino IDE. I completely missed the individual tests step and soldered them all on to the board, so my addresses ended up being printed in serial monitor as a list of 20. I had no idea whether the order was same as their physical location on the wire. So I ended up spending some time applying heat to individual sensor and check which one has a change in value. By doing this I figure out an order of all the addresses that aligned with their order on the wire. Code below:
// This Fabduino sketch reads DS18B20 "1-Wire" digital // temperature sensors. // Tutorial: // http://www.hacktronics.com/Tutorials/arduino-1-wire-tutorial.html // modified by Catty Dan Zhang #include <OneWire.h> #include <DallasTemperature.h> // Data wire is plugged into pin 10 on the Fabduino #define ONE_WIRE_BUS 10 // Setup a oneWire instance to communicate with any OneWire devices OneWire oneWire(ONE_WIRE_BUS); // Pass our oneWire reference to Dallas Temperature. DallasTemperature sensors(&oneWire); // Assign the addresses of your 1-Wire temp sensors. // See the tutorial on how to obtain these addresses: // http://www.hacktronics.com/Tutorials/arduino-1-wire-address-finder.html DeviceAddress temp[20] = { {0x28, 0x80, 0xB8, 0x5F, 0x07, 0x00, 0x00, 0xBD}, {0x28, 0xB0, 0x64, 0x20, 0x06, 0x00, 0x00, 0xB6}, {0x28, 0xB0, 0x64, 0x20, 0x06, 0x00, 0x00, 0xB6}, {0x28, 0x14, 0x8E, 0x5F, 0x07, 0x00, 0x00, 0xC8}, {0x28, 0xCE, 0x78, 0x1F, 0x06, 0x00, 0x00, 0xB2}, {0x28, 0x6E, 0xBF, 0x20, 0x06, 0x00, 0x00, 0x4F}, {0x28, 0x9E, 0x8E, 0x20, 0x06, 0x00, 0x00, 0x74}, {0x28, 0xDE, 0x21, 0x21, 0x06, 0x00, 0x00, 0xD2}, {0x28, 0x29, 0xE0, 0x5F, 0x07, 0x00, 0x00, 0xDC}, {0x28, 0x59, 0xB1, 0x5F, 0x07, 0x00, 0x00, 0x1C}, {0x28, 0x79, 0x75, 0x5F, 0x07, 0x00, 0x00, 0x97}, {0x28, 0x75, 0xA8, 0x5F, 0x07, 0x00, 0x00, 0x58}, {0x28, 0x3D, 0x19, 0x60, 0x07, 0x00, 0x00, 0xDC}, {0x28, 0x33, 0x02, 0x60, 0x07, 0x00, 0x00, 0xC3}, {0x28, 0x6B, 0x6D, 0x5F, 0x07, 0x00, 0x00, 0xE0}, {0x28, 0x87, 0x26, 0x60, 0x07, 0x00, 0x00, 0xFF}, {0x28, 0x67, 0x0D, 0x60, 0x07, 0x00, 0x00, 0x5E}, {0x28, 0x57, 0xF7, 0x5F, 0x07, 0x00, 0x00, 0x7A}, {0x28, 0xB7, 0xD2, 0x5F, 0x07, 0x00, 0x00, 0x79}, {0x28, 0x7F, 0xF8, 0x5E, 0x07, 0x00, 0x00, 0x8D} }; void setup(void) { // start serial port Serial.begin(115200); // Start up the library sensors.begin(); // set the resolution to 10 bit (good enough?) for (int i = 0; i < 20; i++) { sensors.setResolution(temp[i], 10); } } void printTemperature(DeviceAddress deviceAddress) { float temp=sensors.getTempC(deviceAddress);; if (temp == -127.00) { Serial.print("Error getting temperature"); } else { Serial.println(temp); } } void loop(void) { //delay(200); sensors.requestTemperatures(); for (int j = 0; j < 20; j++) { printTemperature(temp[j]); } }
To send the data with a float number to Processing, in Arduino the "Serial.Write" won't work. Instead the "Serial.println" will write a string and will need to be translated to float number in Processing. Here is what I figured how to do it after searching through several forums about this issue:
Then I did a basic program for visualizing the heat pattern. It is far from what I would like it to be as a visualization, but given the time restrain after making and trouble shooting the new input board, I decided to get a clear picture of what's going on with it first to move forward to the next steps.
//by Catty Dan Zhang //Dallas one-wire temperature import processing.serial.*; Serial myPort; int linefeed=10; String myString=null; float temp; int num=20; int dx, dy; int i=0; int x, y; int n; int y01, y02; void setup() { size(800, 600, P2D); background(255); printArray(Serial.list()); myPort = new Serial(this, Serial.list()[3], 115200); myPort.clear(); } void draw() { dx=width/6; dy=height/5; while (myPort.available() > 0) { myString = myPort.readStringUntil(linefeed); if (myString != null) { //print(myString); // Prints String temp=float(myString); // Converts and prints float println(temp); ///////find location to draw println(i); n=i%num; // map to 20 spots y01=(n/4+1)%2; //odd column=1, even column=0 y02=(n/4+2)%2; //odd column=0, even column=1 x=width-(n/4+1)*dx; // find x coordinates y=y01*(n%4+1)*dy+y02*(height-(n%4+1)*dy); //find y coordinates ellipseMode(CENTER); fill(temp*16%255, 90, 90,150); noStroke(); ellipse(x, y, temp*4, temp*4); textSize(10); textAlign(CENTER, CENTER); fill(255); text(myString, x, y); i++; } } myPort.clear(); }
I was hoping to start mapping the data to a 3D frame following certain logic(unknown!). This is the very basic 3d test in Processing without data from the sensor:
However, first try on mapping the actual data wasn't quite successful. The rotation and camera angle made it hard to mask the previous frame- needed to figure out a way to sync serial timing and framerate next.
Thank you for reading!