Skip to content

Commit

Permalink
feat: add atrai bike code
Browse files Browse the repository at this point in the history
  • Loading branch information
felixerdy committed Apr 29, 2024
1 parent 96ac549 commit c1dff64
Show file tree
Hide file tree
Showing 8 changed files with 1,687 additions and 0 deletions.
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,8 @@ A mobile measurement station that measures temperature, relative humidity, parti

- [senseBox:bike v0](senseBox-bike-v0): The first version of the senseBox:bike tested in the Futurium
- [senseBox:bike MCUS2](senseBox-bike-mcus2): The second version of the senseBox:bike with a new microcontroller and BLE-Bee. Used for the [Essen auf Rädern](https://essen.aufraedern.org/) project
- [senseBox:bike Atrai Bike](senseBox-bike-atrai): The third version of the senseBox:bike with the new microcontroller, BLE-Bee, Display and SPS30. Used for the [Atrai Bike](https://atrai.bike/) project

### License

This project is licensed under the MIT License - see the [LICENSE.md](LICENSE.md) file for details
1,227 changes: 1,227 additions & 0 deletions senseBox-bike-atrai/bicycle_loading_bitmap.h

Large diffs are not rendered by default.

98 changes: 98 additions & 0 deletions senseBox-bike-atrai/display.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
#include "display.h"

Adafruit_SSD1306 SBDisplay::display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
QRCode SBDisplay::qrcode;
Adafruit_MAX17048 SBDisplay::maxlipo;

void SBDisplay::begin() {
display.begin(SSD1306_SWITCHCAPVCC, 0x3D);
display.display();
delay(100);
display.clearDisplay();

if (!maxlipo.begin()) {
Serial.println(F("Couldnt find Adafruit MAX17048?\nMake sure a battery is plugged in!"));
while (1)
delay(10);
}
}

void SBDisplay::drawProgressbar(int x, int y, int width, int height, int progress) {
progress = progress > 100 ? 100 : progress; // set the progress value to 100
progress = progress < 0 ? 0 : progress; // start the counting to 0-100
float bar = ((float)(width - 1) / 100) * progress;
display.drawRect(x, y, width, height, WHITE);
display.fillRect(x + 2, y + 2, bar, height - 4, WHITE); // initailize the graphics fillRect(int x, int y, int width, int height)
}



void SBDisplay::showLoading(String msg, float val) {
int dsplW = 128;
int dsplH = 64;
int prgsW = 120;
int prgsH = 8;
display.clearDisplay();
drawProgressbar(4, (dsplH - 12) - prgsH - 4, prgsW, prgsH, val * 100);
display.setCursor(4, dsplH - 12);
display.setTextSize(1);
display.setTextColor(WHITE, BLACK);
display.println(msg);
display.display();
}

void SBDisplay::showSystemStatus() {
display.clearDisplay();
display.setCursor(0, 0);
display.setTextSize(1);
display.setTextColor(WHITE, BLACK);

display.println(F("Batt Percent: "));
display.setTextSize(2);
display.print(maxlipo.cellPercent(), 1);
display.println(" %");

display.println("");

display.setTextSize(1);
display.println(F("(Dis)Charge rate : "));
display.setTextSize(2);
display.print(maxlipo.chargeRate(), 1);
display.println(" %/hr");

display.display();
}

void SBDisplay::drawQrCode(const char *qrStr, const char *lines[]) {
display.clearDisplay();
uint8_t qrcodeData[qrcode_getBufferSize(3)];
qrcode_initText(&qrcode, qrcodeData, 3, ECC_MEDIUM, qrStr);

// Text starting point
int cursor_start_y = 10;
int cursor_start_x = 4;
int font_height = 12;

// QR Code Starting Point
int offset_x = 62;
int offset_y = 3;

for (int y = 0; y < qrcode.size; y++) {
for (int x = 0; x < qrcode.size; x++) {
int newX = offset_x + (x * 2);
int newY = offset_y + (y * 2);

if (qrcode_getModule(&qrcode, x, y)) {
display.fillRect(newX, newY, 2, 2, 1);
} else {
display.fillRect(newX, newY, 2, 2, 0);
}
}
}
display.setTextColor(1, 0);
for (int i = 0; i < 4; i++) {
display.setCursor(cursor_start_x, cursor_start_y + font_height * i);
display.println(lines[i]);
}
display.display();
}
28 changes: 28 additions & 0 deletions senseBox-bike-atrai/display.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#ifndef MY_DISPLAY_H
#define MY_DISPLAY_H

#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <qrcode.h>
#include <Adafruit_MAX1704X.h>

#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1

class SBDisplay {
public:
static void begin();
static void showSystemStatus();
static void drawQrCode(const char *qrStr, const char *lines[]);
static void showLoading(String msg, float val);
static void drawProgressbar(int x, int y, int width, int height, int progress);

private:
static Adafruit_SSD1306 display;
static QRCode qrcode;
static Adafruit_MAX17048 maxlipo;
};
#endif // MY_DISPLAY_H
49 changes: 49 additions & 0 deletions senseBox-bike-atrai/initSensors.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
void initBMX() {
// Try to initialize!
if (!mpu.begin(0x68, &Wire1)) {
Serial.println("MPU6050 Chip wurde nicht gefunden");
return;
} else {
Serial.println("MPU6050 Found!");
mpu.setAccelerometerRange(MPU6050_RANGE_8_G);
mpu.setGyroRange(MPU6050_RANGE_500_DEG);
mpu.setFilterBandwidth(MPU6050_BAND_21_HZ);
delay(100);
};
}

void initToF() {
Wire.begin();
Wire.setClock(1000000); //Sensor has max I2C freq of 1MHz
sensor_vl53l8cx_top.begin();
sensor_vl53l8cx_top.init_sensor();
sensor_vl53l8cx_top.vl53l8cx_set_ranging_frequency_hz(30);
sensor_vl53l8cx_top.vl53l8cx_set_resolution(VL53L8CX_RESOLUTION_8X8);
sensor_vl53l8cx_top.vl53l8cx_start_ranging();
};

void initSPS() {
int errorCount = 0;
int16_t ret;
uint8_t auto_clean_days = 4;
uint32_t auto_clean;

delay(2000);

sensirion_i2c_init();
while (sps30_probe() != 0) {
Serial.print("SPS sensor probing failed\n");
delay(500);
}
ret = sps30_set_fan_auto_cleaning_interval_days(auto_clean_days);
if (ret) {
Serial.print("error setting the auto-clean interval: ");
Serial.println(ret);
}

ret = sps30_start_measurement();
if (ret < 0) {
Serial.print("error starting measurement\n");
}
Serial.println("Starting SPS Measurements");
}
192 changes: 192 additions & 0 deletions senseBox-bike-atrai/senseBox-bike-mcus2.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
// First sketch for the senseBox:bike working with the second generation for the MCU
// SPS is disabled
//

#include <SenseBoxBLE.h>
#include <SDConfig.h>
#include <SD.h>
#include <Adafruit_HDC1000.h>
#include <sps30.h>
#include <Adafruit_MPU6050.h>
#include <NewPing.h> // http://librarymanager/All#NewPing
#include "display.h"

#include <vl53l8cx_class.h>




// Accelerometer and Gyroscope
Adafruit_MPU6050 mpu;
// Temperatur and humidity
Adafruit_HDC1000 HDC = Adafruit_HDC1000();
// ToF
VL53L8CX sensor_vl53l8cx_top(&Wire, -1, -1);

int period = 1000;
unsigned long time_now = 0;
bool recording = false;
long last;
long time_start = 0;

float temp = 0;
float humi = 0;
float pm1 = 0;
float pm25 = 0;
float pm4 = 0;
float pm10 = 0;
float accX = 0;
float accY = 0;
float accZ = 0;
float distance = 0;
struct sps30_measurement m;


float sumAccZ;
float sumAccY;
float sumAccX;

int temperatureCharacteristic = 0;
int humidityCharacteristic = 0;
int PMCharacteristic = 0;
int accelerationCharacteristic = 0;
int distanceCharacteristic = 0;
float status;

String name;

// init all sensors
// todo: give feedback through LED if all is working?
void initsSensors() {
pinMode(IO_ENABLE, OUTPUT);
digitalWrite(IO_ENABLE, LOW);
delay(1000);
Serial.print("ToF...");
SBDisplay::showLoading("Init ToF...", 0.2);
initToF();
// ATTENTION! SPS Disabled for essen-auf-raedern
Serial.print("SPS30...");
SBDisplay::showLoading("Init SPS30...", 0.3);
initSPS();
Serial.println("done!");
Serial.print("MPU6050...");
SBDisplay::showLoading("Init MPU6050...", 0.4);
initBMX();
Serial.println("done!");
Serial.print("HDC1080...");
SBDisplay::showLoading("Init HDC1080...", 0.5);

if (!HDC.begin()) {
Serial.println("Couldn't find HDC1080!");
}
Serial.println("done!");
Serial.print("Propeller...");
SBDisplay::showLoading("Ventilation...", 0.6);
pinMode(3, OUTPUT);
delay(100);
digitalWrite(3, HIGH);
SBDisplay::showLoading("Sensors done...", 0.7);
Serial.println("done!");
}

// set measurements for acceleration, distance, humidity and temperature
void setMeasurements() {
getAccAmplitudes(&sumAccX, &sumAccY, &sumAccZ);
temp = HDC.readTemperature();
humi = HDC.readHumidity();
callSPS();

pm10 = m.mc_10p0;
pm25 = m.mc_2p5;
pm4 = m.mc_4p0;
pm1 = m.mc_1p0;

distance = getVl53l8cxMin();
}

// starts bluetooth and sets the name according to the Bluetooth Bee
// TODO: can the ID be seen on the hardware?
void startBluetooth() {
Serial.print("Set up Bluetooth");
SenseBoxBLE::start("senseBox-BLE");
delay(1000);
name = "senseBox:bike [" + SenseBoxBLE::getMCUId() + "]";
SenseBoxBLE::setName(name);
Serial.println(name);
delay(1000);
Serial.print("Adding BLE characteristics...");
SenseBoxBLE::addService("CF06A218F68EE0BEAD048EBC1EB0BC84");
temperatureCharacteristic = SenseBoxBLE::addCharacteristic("2CDF217435BEFDC44CA26FD173F8B3A8");
humidityCharacteristic = SenseBoxBLE::addCharacteristic("772DF7EC8CDC4EA986AF410ABE0BA257");
PMCharacteristic = SenseBoxBLE::addCharacteristic("7E14E07084EA489FB45AE1317364B979");
accelerationCharacteristic = SenseBoxBLE::addCharacteristic("B944AF10F4954560968F2F0D18CAB522");
distanceCharacteristic = SenseBoxBLE::addCharacteristic("B3491B60C0F34306A30D49C91F37A62B");
Serial.println("done!");
}

// sends phenomenas to the given BT characteristics
bool writeToBluetooth() {
bool connected = SenseBoxBLE::write(temperatureCharacteristic, temp);
SenseBoxBLE::write(humidityCharacteristic, humi);
SenseBoxBLE::write(PMCharacteristic, pm1, pm25, pm4, pm10);
SenseBoxBLE::write(accelerationCharacteristic, sumAccX, sumAccY, sumAccZ);
SenseBoxBLE::write(distanceCharacteristic, distance);

return connected;
}

void resetVariables() {
sumAccX = 0;
sumAccY = 0;
sumAccZ = 0;
}

void setup() {
Serial.begin(9600);
delay(1000);
Serial.println("Starting Sketch!");
SBDisplay::begin();
Serial.println("Initializing sensors..");
SBDisplay::showLoading("Init Sensors...", 0.1);
initsSensors();
Serial.println("Sensor init done! ");
SBDisplay::showLoading("Setup BLE...", 0.8);
startBluetooth();
SBDisplay::showLoading("BLE done...", 0.9);
Serial.println("Bluetooth done!");
delay(500);
SBDisplay::showLoading("Start measurements...", 1);
}

void loop() {
SenseBoxBLE::poll();
time_start = millis();

// set global variables for measurements
setMeasurements();
// write measurements to bluetooth
bool isConnected = writeToBluetooth();
// reset acceleration values
resetVariables();

if (!isConnected) {
String bleId = "[" + SenseBoxBLE::getMCUId() + "]";
String bleIdBegin = bleId.substring(0, bleId.length() / 2);
String bleIdEnd = bleId.substring(bleId.length() / 2);
const char *MESSAGE_CONFIGURE_WIFI[4] = {
"senseBox",
"bike",
bleIdBegin.c_str(),
bleIdEnd.c_str()
};
SBDisplay::drawQrCode(name.c_str(), MESSAGE_CONFIGURE_WIFI);
} else {
SBDisplay::showSystemStatus();
}

time_now = millis();
while (millis() < time_start + period) {
SenseBoxBLE::poll();
delay(5);
}
}
Loading

0 comments on commit c1dff64

Please sign in to comment.