diff --git a/IoT/Rabbit10DOF.mp4 b/IoT/Rabbit10DOF.mp4 new file mode 100644 index 0000000..450ea97 Binary files /dev/null and b/IoT/Rabbit10DOF.mp4 differ diff --git a/IoT/SensorNode.adoc b/IoT/SensorNode.adoc index e54f48a..90c36b5 100644 --- a/IoT/SensorNode.adoc +++ b/IoT/SensorNode.adoc @@ -255,10 +255,256 @@ https://en.wikipedia.org/wiki/Leonhard_Euler[Leonhard Euler] ==== -=== Save Data +=== Save/Sending the Data + +This raw data can then be sent over the network to the central application. + +This will be the subject of another Lab Lesson === Visualizing Data +To visualize the data, we've put together a basic **Processing** sketch that loads a 3D model and renders it using the data generated by the AHRS sketch. + + +==== The tools, languages, and frameworks + +===== Processing + +Processing is an open-source graphical library and integrated development environment (IDE) built for the electronic arts, new media art, and visual design communities with the purpose of teaching non-programmers the fundamentals of computer programming in a visual context. + +Processing uses the Java language, with additional simplifications such as additional classes and aliased mathematical functions and operations. It also provides a graphical user interface for simplifying the compilation and execution stage. + +The Processing language and IDE were the precursor to other projects including Arduino, Wiring and p5.js. + +===== p5.js + +In 2013, Lauren McCarthy created p5.js, a native JavaScript alternative to Processing.js that has the official support of the Processing Foundation. + +===== Processing.py + +Python Mode for Processing, or Processing.py is a Python interface to the underlying Java toolkit. It was chiefly developed by Jonathan Feinberg starting in 2010, with contributions from James Gilles and Ben Alkov + + +===== Three.js + +Three.js is a cross-browser JavaScript library and Application Programming Interface (API) used to create and display animated 3D computer graphics in a web browser. Three.js uses WebGL. + + +[NOTE] +==== +**ThreeJS** is a wrapper around the browser’s native WebGL API. It’s the de facto standard 3D library — there are others, like BabylonJS, but Three is just miles more popular. The native browser APIs are… painful to work with, you can think of ThreeJS kinda like a jQuery for in-browser 3D graphics. Doesn’t give you anything that’s not already there, it just wraps it all into a user-friendly API + +**P5** is not a 3d graphics library, it’s an API for doing creative coding: things like procedural generation, natural simulations etc. It has some 3D features because it wraps the native WebGL API, but that’s not it’s core purpose. It is a artistic and teaching tool — it is occasionally used in production outside of artistic audio/visual stuff, but not often. It’s basically the JS version of Processing. + +==== + +https://www.slideshare.net/victorporof/processingjs-vs-threejs[More: Processing.js vs. three.js] + + +==== Requirements + +- https://processing.org/[Processing 2.x] +- https://code.google.com/archive/p/saitoobjloader/#Download[OBJ Loader library for Processing] +- http://www.lagers.org.uk/g4p/[G4P GUI library for Processing] + +[NOTE] +==== +The OBJ library is required to load 3D models. It isn't strictly necessary and you could also render a boring cube in Processing, but why play with cubes when you have rabbits?! +==== + + +==== Write the Processing Sketch + +.Processing Sketch +[source,c] +---- +import processing.serial.*; +import java.awt.datatransfer.*; +import java.awt.Toolkit; +import processing.opengl.*; +import saito.objloader.*; +import g4p_controls.*; + +float roll = 0.0F; +float pitch = 0.0F; +float yaw = 0.0F; +float temp = 0.0F; +float alt = 0.0F; + +OBJModel model; + +// Serial port state. +Serial port; +String buffer = ""; +final String serialConfigFile = "serialconfig.txt"; +boolean printSerial = false; + +// UI controls. +GPanel configPanel; +GDropList serialList; +GLabel serialLabel; +GCheckbox printSerialCheckbox; + +void setup() +{ + size(400, 500, OPENGL); + frameRate(30); + model = new OBJModel(this); + model.load("bunny.obj"); + model.scale(20); + + // Serial port setup. + // Grab list of serial ports and choose one that was persisted earlier or default to the first port. + int selectedPort = 0; + String[] availablePorts = Serial.list(); + if (availablePorts == null) { + println("ERROR: No serial ports available!"); + exit(); + } + String[] serialConfig = loadStrings(serialConfigFile); + if (serialConfig != null && serialConfig.length > 0) { + String savedPort = serialConfig[0]; + // Check if saved port is in available ports. + for (int i = 0; i < availablePorts.length; ++i) { + if (availablePorts[i].equals(savedPort)) { + selectedPort = i; + } + } + } + // Build serial config UI. + configPanel = new GPanel(this, 10, 10, width-20, 90, "Configuration (click to hide/show)"); + serialLabel = new GLabel(this, 0, 20, 80, 25, "Serial port:"); + configPanel.addControl(serialLabel); + serialList = new GDropList(this, 90, 20, 200, 200, 6); + serialList.setItems(availablePorts, selectedPort); + configPanel.addControl(serialList); + printSerialCheckbox = new GCheckbox(this, 5, 50, 200, 20, "Print serial data"); + printSerialCheckbox.setSelected(printSerial); + configPanel.addControl(printSerialCheckbox); + // Set serial port. + setSerialPort(serialList.getSelectedText()); +} + +void draw() +{ + background(0,0, 0); + + // Set a new co-ordinate space + pushMatrix(); + + // Simple 3 point lighting for dramatic effect. + // Slightly red light in upper right, slightly blue light in upper left, and white light from behind. + pointLight(255, 200, 200, 400, 400, 500); + pointLight(200, 200, 255, -400, 400, 500); + pointLight(255, 255, 255, 0, 0, -500); + + // Displace objects from 0,0 + translate(200, 350, 0); + + // Rotate shapes around the X/Y/Z axis (values in radians, 0..Pi*2) + rotateX(radians(roll)); + rotateZ(radians(pitch)); + rotateY(radians(yaw)); + + pushMatrix(); + noStroke(); + model.draw(); + popMatrix(); + popMatrix(); + //print("draw"); +} + +void serialEvent(Serial p) +{ + String incoming = p.readString(); + if (printSerial) { + println(incoming); + } + + if ((incoming.length() > 8)) + { + String[] list = split(incoming, " "); + if ( (list.length > 0) && (list[0].equals("Orientation:")) ) + { + roll = float(list[1]); + pitch = float(list[2]); + yaw = float(list[3]); + buffer = incoming; + } + if ( (list.length > 0) && (list[0].equals("Alt:")) ) + { + alt = float(list[1]); + buffer = incoming; + } + if ( (list.length > 0) && (list[0].equals("Temp:")) ) + { + temp = float(list[1]); + buffer = incoming; + } + } +} + +// Set serial port to desired value. +void setSerialPort(String portName) { + // Close the port if it's currently open. + if (port != null) { + port.stop(); + } + try { + // Open port. + port = new Serial(this, portName, 115200); + port.bufferUntil('\n'); + // Persist port in configuration. + saveStrings(serialConfigFile, new String[] { portName }); + } + catch (RuntimeException ex) { + // Swallow error if port can't be opened, keep port closed. + port = null; + } +} + +// UI event handlers + +void handlePanelEvents(GPanel panel, GEvent event) { + // Panel events, do nothing. +} + +void handleDropListEvents(GDropList list, GEvent event) { + // Drop list events, check if new serial port is selected. + if (list == serialList) { + setSerialPort(serialList.getSelectedText()); + } +} + +void handleToggleControlEvents(GToggleControl checkbox, GEvent event) { + // Checkbox toggle events, check if print events is toggled. + if (checkbox == printSerialCheckbox) { + printSerial = printSerialCheckbox.isSelected(); + } +} +---- + + + +==== Run it + +- Run the AHRS Sketch on the Uno +- Run the Processing Sketch on the Processing + + +[NOTE] +==== +Make sure that the appropriate AHRS example sketch is running on the Uno (as described), and that the Serial Monitor is closed. +==== + +.And Voila! +image:./sensors_bunny.png[alt="Processing example"] + +video::Rabbit10DOF.mp4[] + + + + diff --git a/IoT/sensors_bunny.png b/IoT/sensors_bunny.png new file mode 100644 index 0000000..b805eda Binary files /dev/null and b/IoT/sensors_bunny.png differ