Welcome to Hackster!
Hackster is a community dedicated to learning hardware, from beginner to pro. Join us, it's free!
Guntas Singh
Published © GPL3+

FPGArdening v3 by Guntas Singh

A weather monitor that measures 10 environmental properties and sends data to Blynk and over HDMI on the Vidor 4000 (HDMI is still in beta)

AdvancedFull instructions provided1,523
FPGArdening v3 by Guntas Singh

Things used in this project

Hardware components

Arduino MKR Vidor 4000
Arduino MKR Vidor 4000
×1
Arduino MKR ENV Shield
×1
Li-Ion Battery 1000mAh
Li-Ion Battery 1000mAh
×2
Adafruit STEMMA soil sensor
×1
SparkFun SPS30 Particulate sensor
×1
HDMI to microHDMI connector
×1

Software apps and online services

Arduino IDE
Arduino IDE

Hand tools and fabrication machines

Premium Female/Male Extension Jumper Wires, 40 x 6" (150mm)
Premium Female/Male Extension Jumper Wires, 40 x 6" (150mm)

Story

Read more

Code

FPGArdening code

Arduino
Upload it to the Vidor and open up the Serial Monitor to visualise the values sent to Blynk and HDMI.
#include "VidorGraphics.h"
#include "Vidor_GFX.h"

Vidor_GFX  vdgfx;

#include <Wire.h>
#include <SPI.h>
#include <Arduino_MKRENV.h>
#include <Adafruit_seesaw.h>
#include <sps30.h>

Adafruit_seesaw ss;

SPS30 sps30;

#define SP30_COMMS Serial1


#include <SPI.h>
#include <WiFiNINA.h>
#include <BlynkSimpleWiFiNINA.h>
BlynkTimer timer;

#define BLYNK_PRINT Serial

// You should get Auth Token in the Blynk App.
// Go to the Project Settings (nut icon).
char auth[] = "YFirMXKTJpc2LDRXLt23MucsxeuiZXml";

// Your WiFi credentials.
// Set password to "" for open networks.
char ssid[] = "guntas0_2.4GHz";
char pass[] = "0505183207";

void ErrtoMess(char *mess, uint8_t r);
void Errorloop(char *mess, uint8_t r);
void GetDeviceInfo();
bool read_all();

void setup()
{
  // Debug console
  Serial.begin(115200);
  Serial1.begin(115200);

  // Let's start by initializing the FPGA
  if (!FPGA.begin()) {
    Serial.println("Initialization failed!");
    while (1) {}
  }

  sps30.EnableDebugging(0);

  if (! sps30.begin(SP30_COMMS))
    Errorloop((char *) "could not initialize communication channel.", 0);
  if (! sps30.probe()) Errorloop((char *) "could not probe / connect with SPS30.", 0);
  else  Serial.println(F("Detected SPS30."));

  // reset SPS30 connection
  if (! sps30.reset()) Errorloop((char *) "could not reset.", 0);

  if (sps30.start() == true) Serial.println(F("Measurement started"));
  else Errorloop((char *) "Could NOT start measurement", 0);

  GetDeviceInfo();

  if (!ss.begin(0x36)) {
    Serial.println("ERROR! seesaw not found");
  } else {
    Serial.print("seesaw started! version: ");
    Serial.println(ss.getVersion(), HEX);
  }

    // Let's discover which version we are running
  int version = FPGA.version();
  Serial.print("Vidor bitstream version: ");
  Serial.println(version, HEX);

  // Let's also ask which IPs are included in this bitstream
  FPGA.printConfig();

  Blynk.begin(auth, ssid, pass);
  // You can also specify server:
  //Blynk.begin(auth, ssid, pass, "blynk-cloud.com", 80);
  //Blynk.begin(auth, ssid, pass, IPAddress(192,168,1,100), 8080);

  timer.setInterval(1000L, update_);

}

void loop()
{
  Blynk.run();
  timer.run();

}
void update_() {
  //FPGA.begin();
  uint8_t ret;
  struct sps_values val;
  float tempC = ss.getTemp();
  uint16_t soil_data = ss.touchRead(0);
  float temperature = ENV.readTemperature();
  float humidity    = ENV.readHumidity();
  float pressure    = ENV.readPressure();
  float illuminance = ENV.readIlluminance();

  ret = sps30.GetValues(&val);

  Blynk.virtualWrite(V1, tempC);
  Blynk.virtualWrite(V3, soil_data);
  Blynk.virtualWrite(V5, temperature);
  Blynk.virtualWrite(V7, humidity);
  Blynk.virtualWrite(V9, pressure);
  Blynk.virtualWrite(V11, illuminance);
  Blynk.virtualWrite(V13, val.NumPM2);

  Serial.println("printing data: ");
  Serial.println("temp: ");
  Serial.println(temperature);
  Serial.println("°C ; Humidity: ");
  Serial.println(humidity);
  Serial.println("%, Pressure: ");
  Serial.println(pressure);
  Serial.println("soil Moisture: ");
  Serial.println(soil_data);
  Serial.println("Soil Temp in °C: ");
  Serial.println(tempC);
  Serial.println("Number of PM2.5 particles");
  Serial.println(val.NumPM2);

  tv (tempC, soil_data, temperature, humidity, pressure, illuminance);
}

void tv(float tempC, uint16_t sm, float temp, float h, float ap, float lux) {

  vdgfx.fillRect(0, 0, 640, 480, vdgfx.Yellow ());

  vdgfx.text.setColor(vdgfx.Green());
  vdgfx.text.setAlpha(187);
  vdgfx.text.setSize(2);
  vdgfx.text.setCursor(15, 40);
  vdgfx.print("FPGArdening");

  vdgfx.text.setCursor(15, 80);
  vdgfx.print("Stats");

  vdgfx.text.setColor(vdgfx.Blue());
  vdgfx.text.setAlpha(255);
  vdgfx.text.setSize(1);
  vdgfx.text.setCursor(15, 140);
  vdgfx.print("Temperature: ");
  vdgfx.print(temp); vdgfx.print(" C");

  vdgfx.text.setCursor(15, 200);
  vdgfx.print("Humidity: ");
  vdgfx.print(h); vdgfx.print("%");

  vdgfx.text.setCursor(15, 260);
  vdgfx.print("Air Pressure: ");
  vdgfx.print(ap); vdgfx.print(" hPa");

  vdgfx.text.setCursor(15, 320);
  vdgfx.print("Soil Moisture: ");
  vdgfx.print(sm); vdgfx.print("%");

  vdgfx.text.setCursor(15, 400);
  vdgfx.print("Soil Temp in *C: ");
  vdgfx.print(tempC); vdgfx.print("*C");

  vdgfx.text.setCursor(15, 420);
  vdgfx.print("Luminance: ");
  vdgfx.print(lux); vdgfx.print("Analog");

  vdgfx.text.setColor(vdgfx.Blue());
  vdgfx.text.setAlpha(120);
  vdgfx.text.setSize(1);
  vdgfx.text.setCursor(15, 460);
  vdgfx.print("FPGArdening v3 by Guntas");
}

void Errorloop(char *mess, uint8_t r)
{
  if (r) ErrtoMess(mess, r);
  else Serial.println(mess);
  Serial.println(F("Program on hold"));
  for (;;) delay(100000);
}

void ErrtoMess(char *mess, uint8_t r)
{
  char buf[80];

  Serial.print(mess);

  sps30.GetErrDescription(r, buf, 80);
  Serial.println(buf);
}

void GetDeviceInfo()
{
  char buf[32];
  uint8_t ret;
  SPS30_version v;

  //try to read serial number
  ret = sps30.GetSerialNumber(buf, 32);
  if (ret == ERR_OK)  {
    Serial.print(F("Serial number : "));
    if (strlen(buf) > 0)  Serial.println(buf);
    else Serial.println(F("not available"));
  }
  else
    ErrtoMess((char *) "could not get serial number.", ret);

  // try to get product name
  ret = sps30.GetProductName(buf, 32);
  if (ret == ERR_OK)  {
    Serial.print(F("Product name : "));

    if (strlen(buf) > 0)  Serial.println(buf);
    else Serial.println(F("not available"));
  }
  else
    ErrtoMess((char *) "could not get product name.", ret);

  // try to get version info
  ret = sps30.GetVersion(&v);
  if (ret != ERR_OK) {
    Serial.println(F("Can not read version info"));
    return;
  }

  Serial.print(F("Firmware level: "));  Serial.print(v.major);
  Serial.print("."); Serial.println(v.minor);

  if (SP30_COMMS != I2C_COMMS) {
    Serial.print(F("Hardware level: ")); Serial.println(v.HW_version);

    Serial.print(F("SHDLC protocol: ")); Serial.print(v.SHDLC_major);
    Serial.print("."); Serial.println(v.SHDLC_minor);
  }

  Serial.print(F("Library level : "));  Serial.print(v.DRV_major);
  Serial.print(".");  Serial.println(v.DRV_minor);
}

Credits

Guntas Singh
2 projects • 16 followers
Amateur physicist and IGCSE student. Studying Arduino and Verilog (once I receive my MKR Vidor 4000)
Contact

Comments

Please log in or sign up to comment.