ITP blogcontactabout

Connected Devices & Network Interactions

Connected Spirulina - Final Documentation

Spirulina, Fabrication, System Diagram

Background on Spirulina

Spirulina is a blue-green algae that grows naturally in fresh water lakes in Africa and North America. Spirulina has existed for approximately 3.6 billion years, and was consumed as a traditional food in 9th Century Chad and by Aztecs in 16th Century Mexico. Unlike seaweed, each individual Spirulina organism is only about as thick as 3-5 pieces of paper, but is packed with protein, minerals and anti-oxidants.

Spirulina has made a resurgence in large part because it has the potential to play an integral role in lower the carbon footprint of the agricultural sector. Spirulina farming requires 19x less CO2 to produce the same amount of protein compared to beef. It also requires less water than traditional farming and can be grown indoors with not much space. It's also loaded with various nutrients and antioxidants including protein, vitamin B1, vitamin B2, Copper, and Iron.

We Are The New Farmers

We Are The New Farmers is an urban farming lab who specializes in growing fresh Spirulina, a nutrient rich sustainable algae. They cultivate their Spirulina in their 1,250 soft facility in the Brooklyn Army Terminal, Sunset Park. They have developed closed tanks that provide for the growing conditions of the micro algae. Their value proposition as a company is that they sell their spirulina fresh and not dried (which is usually how its consumed). They argue that dried spirulina is dead and the nutrients are not as readily available. Their fresh spirulina is still unprocessed and contains certain enzymes and nutrients that dried spirulina does not. It also apparently tastes better than dried spirulina...

Goal for the Project

Spirulina thrives in alkaline, brackish water but can live in a wide range of compositions of water that need to be maintained. There are a multitude of climatic factors influencing the rate of growth and overall yield of spirulina including but not limited to temperature and pH levels. For this project I embedded 3 sensors (temperature, pH, and turbidity) in a waterproof enclosure to track the culture and medium over time.

The goal is to be able to host that data persistently on a webpage where it can be monitored remotely. I built my own bioreactor at home and created a system that would read, store, and display data persistently over time.

Technical Description

Using Tom Igoe's ArduinoHTTPClient as the boilerplate, I was able to convert the sensor readings to JSON strings and send those strings to a server hosted on Glitch. The server sends those readings to a database hosted by MongoDB. The server fetches the data through two separate get requests: 1. that takes the readings and displays the immediate sensor value on a webpage and 2. makes a request that fetches the entire database through a for loop and displays a visualization.

Webpage

The immediate sensor values as well as the values accumulated over time are available at https://julians-bioreactor.glitch.me/.

Data Interpretation

Conclusions made over data collection from 5 days:

Next Steps...

Develop an automation system where if pH goes over X level, it can automatically insert X about of bicorbonate medium to lower the pH levels.

Want to decide whether the irrigation system is connected to a separate controller or not
Could have two controllers both subscribed to the same MQTT topic
Probably use one microcontroller though… more complex, more checks and balances

Week 8:

Bioreactor Fabrication, HTTP Client/Server

Client/Server

Spent some time building out the REST API / Client (Arduino) Server (JavaScript/Node.js) relationship I'm going to have to build for this project but came across a few hurdles. I built off of Tom's boilerplate to develop my client side. I got the following output, which I know has successfully connected to my Wi-Fi and is outputting data from my temperature sensor:
Full Code:

#include <SPI.h>
#include <WiFiNINA.h>         // for MKR1010 modules
#include <ArduinoHttpClient.h>
#include <Arduino_JSON.h>
#include "DFRobot_SHT20.h"
#include "arduino_secrets.h"

DFRobot_SHT20    sht20;
byte mac[6];                    // mac address of your device
WiFiSSLClient netSocket;        // network socket to server
const char server[] = SECRET_SERVER;  // server name
String route = "data";         // API route

// the HTTP client is global so you can use it in multiple functions below:
HttpClient client(netSocket, server, 443);
// a JSON variable for the body of your requests:
JSONVar body;

// request timestamp in ms:
long lastRequest = 0;
// interval between requests:
int interval = 10000;

void setup() {
 Serial.begin(9600);              // initialize serial communication  
sht20.initSHT20();                                  // Init SHT20 Sensor
  delay(100);
  sht20.checkSHT20();                                 // Check SHT20 Sensor  

// while you're not connected to a WiFi AP, attempt to connect:
 while ( WiFi.status() != WL_CONNECTED) {
   Serial.print("Attempting to connect to Network named: ");
   Serial.println(SECRET_SSID);           // print the network name (SSID)
   WiFi.begin(SECRET_SSID, SECRET_PASS);  // try to connect
   delay(2000);
 }

 // get your MAC address:
 WiFi.macAddress(mac);

// When you're connected, print out the device's network status:
 IPAddress ip = WiFi.localIP();
 Serial.print("IP Address: ");
 Serial.println(ip);
 Serial.print("MAC Address: ");
 Serial.println(macToString(mac));  

// add the mac address and session key to the body,
 // since they won't change:
 body["macAddress"] = macToString(mac);
 body["sessionKey"] = SECRET_SESSIONKEY;
}

void loop() {
 if (millis() - lastRequest > interval ) {    

// this is your data. It's a JSON object that will go
   // in the other JSON object (the body):
   JSONVar sensorData;    

// read sensor (in this case, a SHT20 temperature sensor):
   temperature = sht20.readTemperature();
   sensorData["temperature"] = temperature;    

// use this for POST:
   postData(JSON.stringify(sensorData));

   //  or use this for GET:
//      getData();
   int transactionID = 539;
   //  or use this to GET one datum:
   //  getDatum(transactionID);
   //  or use this to DELETE one datum:
   //deleteDatum(transactionID);    

// read the status code and body of the response
   int statusCode = client.responseStatusCode();
   String response = client.responseBody();    

// print out the response:
   Serial.print("Status code: ");
   Serial.println(statusCode);
   Serial.print("Response: " );
   Serial.println(response);
   // when there's nothing left to the response,
   client.stop();           // close the request
   // timestamp the time of request:
   lastRequest = millis();
 }
}

void postData(String newData) {
 // set the content type and fill in the POST data:
 String contentType = "application/json";
 // the template for the body of the POST request:
 body["data"] = newData;
 Serial.println(body);
 // make the request
 client.post(route, contentType, JSON.stringify(body));
}

void getData() {
 // set the content type and fill in the body:
 String contentType = "application/json";  

// make the request:
 client.beginRequest();
 client.get(route);
 client.sendHeader("Content-Type", "application/json");
 client.sendHeader("Content-Length", body.length());
 client.beginBody();
 client.println(body);
 client.endRequest();
}

void getDatum(int newData) {
 // set the content type and fill in the body:
 String contentType = "application/json";
 // add the query to the route:
 String request = route + "/";
 request += String(newData);
 // make the request:
 client.beginRequest();
 client.get(request);
 client.sendHeader("Content-Type", "application/json");
 client.sendHeader("Content-Length", body.length());
 client.beginBody();
 client.print(body);
 client.endRequest();
}

void deleteDatum(int newData) {
 // set the content type and fill in the body:
 String contentType = "application/json";
 // the template for the body of the POST request:
 String body = " {\"macAddress\":\"MAC\",\"sessionKey\":\"KEY\"}";
 // replace the template placeholders with actual values:
 body.replace("MAC", macToString(mac));
 body.replace("KEY", SECRET_SESSIONKEY);  

// add the query to the route:
 String request = route + "/";
 request += String(newData);
 // make the request:
 client.beginRequest();
 client.del(request);
 client.sendHeader("Content-Type", "application/json");
 client.sendHeader("Content-Length", body.length());
 client.beginBody();
 client.print(body);
 client.endRequest();
}

// convert the MAC address to a String:
String macToString(byte mac[]) {
 String result;
 for (int i = 5; i >= 0; i--) {
   if (mac[i] < 16) {
     result += "0";
   }
   result += String(mac[i], HEX);
   if (i > 0)  result += ":";
 }
 return result;
}

I tried to then run a simple Node.js server on Glitch and called for the appropriate /Data route on a GET request but couldn't get anything in the log. Hoping to debug this week during office hours. I still think I have some work to do on the server side of things. I've also never built a server in this context before.


Bioreactor / The Farm

I got to go visit the farm in Sunset Park this week, which was fun. I was also gifted all of the basic materials for building my own bioreactor, which I now have running at home.

Week 7:

Wi-Fi, server/client relationship, fabrication

Cloud & Server Stuff

I spent a good amount of time doing trying a bunch of different things... I set up a digital ocean account but had problems logging in with my SSH key: "permission denied (publickey). I also spent a good amount of time getting familiar with the serve side code on Tom's github.

Client Side / Shiftr.io

I spent a lot of time on the client side. I finally got all three of my sensors working:
I tried to send some data over MQTT to shiftr using their provided boilerplate, but came across a few issues. Hoping to get this resolved by next week's class, I'd like to start collecting data and working on fabrication.

Full code, though not working (yet):

#include "DFRobot_SHT20.h"
#include <WiFi.h>
#include <MQTT.h>

float celcius;
char ssid[] = "SpectrumSetup-BD";
const char* pass = "password_here";

WiFiClient net;
MQTTClient client;

unsigned long lastMillis = 0;
DFRobot_SHT20    sht20;

void connect() {
 Serial.print("checking wifi...");
 while (WiFi.status() != WL_CONNECTED) {
   Serial.print(".");
   delay(1000);
 }  

Serial.print("\nconnecting...");
 while (!client.connect("arduino", "connectedspirulina", "mqtt://connectedspirulina:wUuXNrzuo4UjGW2X@connectedspirulina.cloud.shiftr.io")) {
   Serial.print(".");
   delay(1000);
 }  

Serial.println("\nconnected!");  
client.subscribe("/connectedspirulina");
}

void messageReceived(String &topic, String &payload) {
 Serial.println(topic + ": " + payload);
}

void setup(){
 Serial.begin(115200);  // start wifi and mqtt
 WiFi.begin(ssid, pass);
 client.begin("connectedspirulina.cloud.shiftr.io", net); // first argument is your instance domain
 client.onMessage(messageReceived);  

connect();
 
   sht20.initSHT20();                                  // Init SHT20 Sensor
   delay(100);
   sht20.checkSHT20();                                 // Check SHT20 Sensor
}

void loop(){
 client.loop();
 delay(10);  // check if connected
 
if (!client.connected()) {
   connect();
 }

String temperature = String(celcius);  

// publish a message roughly every second.
 if (millis() - lastMillis > 1000) {
   lastMillis = millis();
   client.publish("/connectedspirulina", celcius);    
readTemp();
 }
}void readTemp(void) {  

   float temp = 0;
   temp = sht20.readTemperature();               // Read Temperature    
int sensorValue = analogRead(A0);// read the input on analog pin 0:
   float voltage = sensorValue * (3.3 / 1024.0); // Convert the analog reading (which goes from 0 - 1023) to a voltage (0 - 5V):  
 
   Serial.print(" Temperature:");
   Serial.print(temp, 1);
   Serial.print("C");
   Serial.print("%");
   Serial.print("    Turbidity value in voltage:");
   Serial.print(voltage);
   Serial.println();
   delay(1000);

   celcius = temp;
}
Eventually figured out that the data type (float) was incompatible with publish function from the client side. Working client side MQTT code:

#include <SPI.h>
#include <WiFiNINA.h>
#include <MQTT.h>
#include "DFRobot_SHT20.h"

float celsius;

const char ssid[] = "SpectrumSetup-BD";
const char pass[] = "password_here";

WiFiClient net;
MQTTClient client;

unsigned long lastMillis = 0;

DFRobot_SHT20    sht20;

void connect() {
 Serial.print("checking wifi...");
 while (WiFi.status() != WL_CONNECTED) {
   Serial.print(".");
   delay(1000);
 }  

Serial.print("\nconnecting...");
 while (!client.connect("julian", "connectedspirulina", "IGDJzRCqQVRpOGwU")) {
   Serial.print(".");
   delay(1000);
 }  

Serial.println("\nconnected!");  

client.subscribe("hello");
}

void messageReceived(String &topic, String &payload) {
 Serial.println(topic + ": " + payload);
}

void setup() {
 Serial.begin(115200);  

// start wifi and mqtt
 WiFi.begin(ssid, pass);
 client.begin("public.cloud.shiftr.io", net);
 client.onMessage(messageReceived);

 connect();    

sht20.initSHT20();                                  // Init SHT20 Sensor
   delay(100);
   sht20.checkSHT20();                                 // Check SHT20 Sensor
}

void loop() {
 client.loop();
 delay(10);  

// check if connected
 if (!client.connected()) {
   connect();
 }  

String temperature = String(celsius);  

// publish a message roughly every second.
 if (millis() - lastMillis > 1000) {
   lastMillis = millis();
   client.publish("/hello", temperature);    readTemp();
 }
}

void readTemp(void) {  
//    float humd = sht20.readHumidity();                  // Read Humidity
   float temp = 0;
   temp = sht20.readTemperature();               // Read Temperature    int sensorValue = analogRead(A0);// read the input on analog pin 0:
   float voltage = sensorValue * (3.3 / 1024.0); // Convert the analog reading (which goes from 0 - 1023) to a voltage (0 - 5V):    
   Serial.print(" Temperature:");
   Serial.print(temp, 1);
   Serial.print("C");
//    Serial.print(" Humidity:");
//    Serial.print(humd, 1);
   Serial.print("%");
   Serial.print("    Turbidity value in voltage:");
   Serial.print(voltage);
   Serial.println();
   delay(1000);
   celsius = temp;
}

Fabrication

I've started to put together some very basic drawings to show what the physical device might look like:

Week 6:

Midterm

Description/Deliverables

To reiterate from last week, for my midterm project (and final project) I will be working with We Are The New Famers, an urban farming lab who specializes in growing fresh Spirulina, a nutrient rich sustainable algae. We Are The New Farmers cultivate their Spirulina in their 1,250 sqft facility in the Brooklyn Army Terminal, Sunset Park. Spirulina, like most algae, grows in water. They have developed closed tanks that provide for the growing conditions of the microalgae.

For this midterm, the goal is to prototype an application where sensor readings from a turbidity (density) and a temperature/humidity sensor will be displayed on a webpage (connected via Bluetooth LE).

Application interface screenshot:

Technical Description

At the core of this project is a bluetooth application that allows the sensors being read in the Arduino IDE to be read in JavaScript and display them on a webpage. The first step was to define the characteristics in C, assign to each of them their own unique universal identifier (UUID), and assigning them descriptions (read, notify, and/or write).
The next step was to add each characteristic to the previously defined service - this case titled "ledService"
Finally, writing each of the value in the Arduino loop.
In JavaScript, using a for loop to loop over all of the characteristics.
Finally, also in JavaScript, creating an html element for each of the characteristics and assigning to each of them their own respective UUID to read from.

Troubleshooting

This all went pretty smoothly except that I'm still having issues mapping the value of the turbidity sensor from voltage to NTU (unit of measurement for turbidity). The SKU SEN0189 Turbidity sensor runs on 5V and outputs voltage as the sensor reading, which corresponds to a NTU value:
I found a data sheet that provides an algorithm for the voltage to NTU conversion, which I tried to map to the 3.3 V range that the IoT 33 provides, but didn't fit the corresponding values.
I also tried giving the sensor an external 5V but got a lot of noise and couldn't get a consistent reading. What I'm assuming I'm going to have to do is solder the V-USB pin on the back of the nano IoT 33 so I can run the entire project on 5V. This will also eventually be very helpful for implement the pH sensor, which also runs on 5V.

Week 5:

Bluetooth and Midterm Project Planning

Bluetooth

Coming out of the lecture I thought I had a good understanding of the Bluetooth LE material but after a week of review I've found myself with many questions (and a lot of confusion), most of them on the central (JavaScript) side.

Question #1: How do we call for all of the characteristics?

In class, Tom proposed iterating through all of them with one of his favorite JavaScript for loops. I tried to then plug that variable into the array but to no avail.
Question #2: I'm getting a value printed to my webpage, but what is that value?

In this iteration, I'm calling for the 1st characteristic [0], which in this case should be the temperature in Celcius (I removed the button and LED characteristics from my code because I don't need it). Im getting this value of 102 but I don't know what it means and don't know what it correlates to but it's obviously not the current temperature in Celcius.
Question #3: Once I can solve question #1 and #2 and read all of the characteristics, how can I format them? 

Some documentation or examples in this space would be helpful. As I look towards my midterm assignment for this week where I plan on adding another sensor and more characteristics, I'll need to find a solution for this.


Full arduino and script codes (starts at ConnectToBle function) for reference:

Midterm Project Planning

For my midterm project (and final project) I will be working We Are The New Famers, an urban farming lab who specializes in growing fresh Spirulina, a nutrient rich sustainable algae. We Are The New Farmers cultivate their Spirulina in their 1,250 sqft facility in the Brooklyn Army Terminal, Sunset Park. Spirulina, like most algae, grows in water. They have developed closed tanks that provide for the growing conditions of the microalgae.

For this midterm, the goal is to prototype an application where sensor readings from a turbidity (density) and a temperature/humidity sensor will be displayed on a webpage (connected via Bluetooth LE). The steps for this will be:

1. Get the sensors working
2. Make a webpage that represents the two
3. Use bluetooth to connect the two.


Sensor details:

Analog Turbidity Sensor (SEN0189):
https://wiki.dfrobot.com/Turbidity_sensor_SKU__SEN0189
Breakout board allows the sensor to connects via analog signal output or digital signal output. The unit of measurement for turbidity is NTU - ranging from 0 to 50 (< 0.5 being clear/clean water).

This is a reference chart for the mapping from the output voltage to the NTU according to different temperature. e.g. If you leave the sensor in the pure water, that is NTU < 0.5, it should output “4.1±0.3V” when temperature is 10~50℃.
The implication from the documentation I've gone through is that it doesn't need any particular library (I'm assuming because it the output is . Code I found to get a basic sensor reading:
Temperature/Humidity Sensor (DHT22):

We've gone over the specs of this in class so I'm not going to provide an abundance of detail but going to attach Adafruit's documentation for future reference: https://learn.adafruit.com/dht. I'll also mention that it connects via digital signal output.


System Diagram:

Week 4:

Assignment:
- Familiarize yourself with the basic concepts of Bluetooth LE.
- Use a Bluetooth scanner app to explore Bluetooth LE devices near you.
- Try basic bluetooth connectivity between Arduino and your browser. Rewrite this Bluetooth LE application as a plain JS and HTML application.

Notes/Questions

- Are there other ways than the p5 BLE library to initiate communication?
- "Read from one Characteristic" and "Write to one Characteristic" were relatively easy to implement. I had challenges trying to trying to communicate synchronously and not being able to rely on defining ports and analogRead functions.
- What would ultimately be most useful for me is to walk through an example where the web browser is displaying a sensor read not using Analog or DigitalRead.
- I mentioned this in an office hour with Tom before but I'm still a little confused on how the JavaScript can read the variable created in Arduino (that reads the sensor value) without explicitly stating it.
- An example showing how to pass datatypes might be useful:

myBLE.read(myCharacteristic, gotValue);  // You can also pass in the dataType  // Options: 'unit8', 'uint16', 'uint32', 'int8', 'int16', 'int32', 'float32', 'float64', 'string'  // myBLE.read(myCharacteristic, 'string', gotValue);}

- Arduino code I wrote (based off "DHTtester" in DHT library and "read one character" from Tom's examples)

#include <ArduinoBLE.h>
#include "DHT.h"#define DHTPIN 2
#define DHTTYPE DHT22BLEService tempService("19B10010-E8F2-537E-4F6C-D104768A1214"); // create service

BLEIntCharacteristic buttonCharacteristic("19B10012-E8F2-537E-4F6C-D104768A1214", BLERead | BLENotify);
DHT dht(DHTPIN, DHTTYPE);
int sensorValue = 0;void setup() {
 Serial.begin(9600);  

//initialize DHT sensor
Serial.println(F("DHTxx test!"));
 dht.begin();  //initialize BLE
 while (!Serial);

 if (!BLE.begin()) {
   Serial.println("starting BLE failed!");    
while (1);
 }BLE.setLocalName("Temp");

BLE.setAdvertisedService(tempService); // what exactly does this do?
tempService.addCharacteristic(buttonCharacteristic);
buttonCharacteristic.writeValue(0); // what other types of characteristics can you add? is buttonCharacteristic a preset variable part of the p5BLE library?
BLE.advertise();Serial.println("Bluetooth device active, waiting for connections...");
}
void loop() {  BLE.poll();  float h = dht.readHumidity();
 // Read temperature as Celsius (the default)
 float t = dht.readTemperature();
 // Read temperature as Fahrenheit (isFahrenheit = true)
 float f = dht.readTemperature(true);//  sensorValue = f; //
 Serial.println(f);
 buttonCharacteristic.writeValue(f); // how else can I read this value?
}

Week 3:

Assignment:
- Program a microcontroller display to show the time and the state of a sensor attached to your controller.
- Try to control lunar lander or Zoom, or another application with mouse and keyboard

Description

Relatively simple application: I showed data from a DH22 Temperature/Humidity sensor onto an OLED display. Previously, I got a reading using a potentiometer and also attempted to connect an INA 219 current sensor to the OLED but couldn't get the data to show on the display (I believe it's a circuit/electrical issue). Images attached below are the circuit diagram for the INA/OLED setup (using i2c serial protocol, doubling down on A4 and A5 pins) as well as the working prototype for the temperature/humidity sensor.

For the HID component of the homework I was easily able to implement Tom's HID example (having four pushbuttons control the arrow keys): https://github.com/tigoe/hid-examples/blob/main/KeyboardFourPushbuttons/KeyboardFourPushbuttons.ino. However, I wasn't able to get it to work for the lunar lander game and I'm not sure why.

Technical Component

All of this is built off of Tom Igoe's OLED display repo on his github: https://github.com/tigoe/display-examples/tree/main/OLED_Examples/SSD1306_QRCode_Test.

Link to the DHT/OLED code: https://github.com/juliantisomathews/DHTOLED

For the temperature/humidity sensor prototype the code was pretty straight forward: 

#include "DHT.h"
#include <Wire.h>
#include <Adafruit_SSD1306.h>

#include<Fonts/FreeSans9pt7b.h>
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
#define OLED_RESET    0  // Reset pin for display (0 or -1 if no reset pin)
#define DHTPIN 2     // Digital pin connected to the DHT sensor
#define DHTTYPE DHT22   // DHT 22  (AM2302), AM2321DHT dht(DHTPIN, DHTTYPE); // initialize DHT sensor
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

void setup() {
 // initialize serial and wait 3 secs for serial monitor to open:
 Serial.begin(9600);  dht.begin(); // initializes sensor
 
 if (!Serial);
 // I2C address is 0x3C, or 3D for some 128x64 modules:
 if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
   Serial.println("Display setup failed");
   while (true);
 }
   // set fonts botforh display:
 display.setFont(&FreeSans9pt7b);
 Serial.println("Display is good to go");
}

void loop() {
  delay(250);  // Reading temperature or humidity takes about 250 milliseconds!
 // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
 float h = dht.readHumidity();
 // Read temperature as Fahrenheit (isFahrenheit = true)
 float f = dht.readTemperature(true);  // clear the display:
 display.clearDisplay();
 // set the text size to 1:
 display.setTextSize(1);
 // set the text color to white:
 display.setTextColor(SSD1306_WHITE);
 
 // move the cursor to 0,0:
 display.setCursor(0, 12);
 // print the seconds:
 display.print("secs:");
 display.print(millis() / 1000);
 
 // move the cursor down 20 pixels:
 display.setCursor(0, 30);
 // print a sensor reading:
 display.print("Humidity:");
 display.print(h);  display.print("Temp (F):");
 display.print(f);
 
 // push everything out to the screen:
 display.display();
}

For the INA sensor example I'm still not exactly sure what went wrong. According to Tom the wiring and the code looked good; I believe it may have been interference from the 5v battery that the current sensor was pulling data from (but also simultaneously giving my Arduino IoT 33 5V through the VIN pin).


#include <Wire.h>
#include <Adafruit_SSD1306.h>
#include <Adafruit_INA219.h>#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
#define OLED_RESET    0  // Reset pin for display (0 or -1 if no reset pin)Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
Adafruit_INA219 ina219;

void setup() {// generally, just not sure about order of operations here - should i inialize one before the other?  
Serial.begin(9600);

 if (!Serial) delay(3000);
 if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // initializing the OLED display and explicitly calling i2c address"
   Serial.println("Display setup failed");
   while (true);
 }
 
if (! ina219.begin()) { // initializing the the INA 219 chip and calling the i2c address (though adafruit documentation says you only need to explicitly address if using more than one INA board.
   Serial.println("Failed to find INA219 chip");
   while (1) { delay(10); }
 }
}

void loop() {  

float current_mA = 0;
 current_mA = ina219.getCurrent_mA();  Serial.print("Current:       "); Serial.print(current_mA); Serial.println(" mA");  delay(2000); // inputed delay as recommended - not exactly sure how to go about implmeneting millis() conditional statement nor the max frequency though identified the data sheet here: https://cdn-shop.adafruit.com/datasheets/ina219.pdf  display.clearDisplay(); // clear the display
 display.setTextSize(1);
 display.setCursor(0,20);
 display.print("secs:");
 display.print(millis() / 1000);  display.print("sensor:");
 display.print(current_mA);  display.display();
 
}


For the HID component, the only changes I made were the characters to print when the buttons are pushed:

char buttonChar[] = {KEY_UP_ARROW, KEY_DOWN_ARROW, KEY_RIGHT_ARROW, KEY_LEFT_ARROW};

Week 2:

Assignment: Build a browser-based application that you can transfer from your personal computer to a mobile device via a QR code.

Description

I think the most intriguing part about QR codes is their accessibility: they let anyone with a smartphone to access information within seconds.

On February 9th 2021, Huge Ma, a 31-year old software engineer developed a free website that complies availability from the three main city and state New York vaccine systems and sends the information in real time to Twitter. It cost Mr. Ma less than $50 to build, yet it offers an easier way to spot appointments than the city and state's official systems do (https://www.nytimes.com/2021/02/09/nyregion/vaccine-website-appointment-nyc.html).

I uploaded the website domain (https://www.turbovax.info/) to a QR code and displayed it on a screen with a caption. It would be great if the city put these everywhere to let people know about it and access the information easily is an intriguing concept...

Technical Component

All of this is built off of Tom Igoe's OLED display repo on his github: https://github.com/tigoe/display-examples/tree/main/OLED_Examples/SSD1306_QRCode_Test.

The main difficulty I was having was getting the camera on my phone to read the QR code on my OLED display. Changing the size of the display has proven difficult. When I increase the screen height by 30% I get a QR code that is too big for the display and in contrast when I do it by 20% the QR code display doesn't change at all.

int offset = 10;
 int blockSize = (display.height()*1.2 - (offset * 2)) / qrcode.size;

int offset = 10;
 int blockSize = (display.height()*1.3 - (offset * 2)) / qrcode.size;


I also tried without the offset and got similar:

int blockSize = qrcode.size / 18;

int blockSize = qrcode.size / 24;


Update: The split yellow/blue colors of the display was causing my issue (see images above). By rotating the QR code 180 degrees out of the yellow zone I was able to get it to work:

int x = 3;
 display.setRotation(x);

Week 1:

Assignment: Build your own browser-based application that communicates with a microcontroller using the HTML DOM elements similar to this example. Don’t use p5.js except for the serial port connection.

Description

I built off of Tom's example and added an additional button and an additional potentiometer with the main goal of bettering my understanding of how the JSON packaged variables exported from arduino communicate with JavaScript and viceversa.

In reference to the images below, the pushbuttons and knobs on the breadboard affect the power buttons on the webpage as well as the brightness and fan speed sliders.

Technical Component

All of this is built off of Tom Igoe's "serial port" repo: https://github.com/tigoe/html-for-conndev/tree/main/serialport

I uploaded my modifications to my own Github: https://github.com/juliantisomathews/SerialPort (includes Arduino code (C++), HTML, CSS, and JavaScript files, and a Readme file with further description).


function serialEvent() {  
// read a line of incoming data:  
var inData = serial.readLine();

// if the line is not empty, parse it to JSON:  
if (inData) {    var sensors = JSON.parse(inData);  
 
// button value:    
// if the button's changed and it's pressed, take action:    

if (sensors.button !== lastButtonState) {      if (sensors.button === 0) {        setPowerState(sensors.button);      }      
// save button value for next time:  
   
lastButtonState = sensors.button;    }
   if (sensors.button2 !== lastSwitchState) {        if (sensors.button2 === 0) {          setSwitchState(sensors.button2);        }      
 
// save button value for next time:        
lastSwitchState = sensors.button2;      }    

// fan slider value:    
setBrightness(sensors.knob2);    
setFanSpeed(sensors.knob);    
     }}

Ultimately, this is the section of the code that reads the incoming JSON variables: "button", "button2", "knob", and "knob2" all correlate to the JSON variables we created and outputted in arduino.