Arduino MKR WiFi 1010
An Arduino MKR WiFi 1010 small board computer with a Grove sensor system compatible carrier board is proposed for controlling and monitoring the OpenAir Collective Direct Air Carbon Capture (DACC) Violet sorbent test prototype. The Violet DACC prototype will be used to evaluate the performance of sorbents to capture CO2 from the air and to determine the best geometry of the Violet design. The MKR WiFi 1010 has the following features:
- SAMD21 Cortex-M0+ 32 bit microcontroller
- u-block NIN-W102 radio module for Wifi and BLE
- Powered by USB cable at 5V
- Cryptochip
- 8 digital pins
- 13 PWM pins
- 1 UART
- 1 SPI
- 1 I2C
- 7 analog inputs
- 1 analog output
- 10 external interrupts
- 256 KB flash memory
- 32 KB SRAM
- Small form factor
Arduino MKR Connector Carrier
The Arduino MKR Connector Carrier has connectors to connect to Grove compatible sensors. The carrier has the following features.
- 5 Analog single Grove input ports
- 1 Analog dual Grove input port
- 5 Digital single Grove input ports
- 1 Digital dual Grove input port
- 1 I2C port
- 1 UART port
- 5V to 3.3V level translators
- DC/DC converter (7 V to 16 V input to +5V and +3.3 V)
Grove Sensor Modules
Five Grove modules are attached to the MKR WiFi 1010 via the carrier board to demonstrate WiFi connectivity, and sampling sensors. This includes four sensors (temperature, water, sound, and Hall), and one LED socket module. The Grove system is made by Seeed Studio and is based on a four wire system (Power, Ground, and 2 signal pins). Pin spacing is 2 mm and has varying compatibility with STEMMA and Gravity connectors/modules.
No image specified. One of the following parameters must be set: fileId, randomGalleryId, fgalId, attId, id, or src.
This demonstration setup contains sensors the I had on hand and are attached in the following ports.
- A0: Temperature Sensor
- A1: Sound Sensor
- D0: Hall Sensor
- D1: Water Sensor
- D2: LED Socket Module
The sensors set is to be replaced once the appropriate CO2, temperature, and pressure sensors have been finalized.
A number of sketch were written to capture sensor data, setup the MKR WiFi 1010 as a webserver and access point, and to demonstrate the Real Time Clock (RTC) that connects to a Network Time Protocol (NTP) service to set the time. These sketches were refined and combined to sample data with a time stamp for each series of sampled data. Samples are taken every 1 second in this demo sketch. A sample of some of the data is shown below.
Serial Monitor Output
SSID: Red2
IP Address: 192.168.1.134
signal strength (RSSI):-54 dBm
Epoch received: 1610340928
1/11/21 23:55:28, Temperature: 23.74 C, Water level: 1, mfield: 1, Sound Level: 16
1/11/21 23:55:29, Temperature: 23.74 C, Water level: 1, mfield: 1, Sound Level: 19
1/11/21 23:55:30, Temperature: 23.82 C, Water level: 1, mfield: 1, Sound Level: 3
1/11/21 23:55:31, Temperature: 23.82 C, Water level: 1, mfield: 1, Sound Level: 47
/* Data deleted. Water was placed on the water sensor
* and my finger was held on the temperature sensor
* to increase the temperature.
*/
1/11/21 23:56:55, Temperature: 23.91 C, Water level: 0, mfield: 1, Sound Level: 10
1/11/21 23:56:56, Temperature: 26.27 C, Water level: 0, mfield: 1, Sound Level: 5
1/11/21 23:56:57, Temperature: 25.39 C, Water level: 0, mfield: 1, Sound Level: 18
1/11/21 23:56:58, Temperature: 28.05 C, Water level: 0, mfield: 1, Sound Level: 15
1/11/21 23:56:59, Temperature: 29.32 C, Water level: 0, mfield: 1, Sound Level: 0
1/11/21 23:57:00, Temperature: 30.50 C, Water level: 0, mfield: 1, Sound Level: 14
1/11/21 23:57:01, Temperature: 30.96 C, Water level: 0, mfield: 1, Sound Level: 13
1/11/21 23:57:02, Temperature: 31.34 C, Water level: 0, mfield: 1, Sound Level: 48
1/11/21 23:57:03, Temperature: 31.62 C, Water level: 0, mfield: 1, Sound Level: 179
1/11/21 23:57:04, Temperature: 31.71 C, Water level: 0, mfield: 1, Sound Level: 46
1/11/21 23:57:05, Temperature: 31.99 C, Water level: 0, mfield: 1, Sound Level: 11
1/11/21 23:57:06, Temperature: 32.18 C, Water level: 0, mfield: 1, Sound Level: 15
1/11/21 23:57:07, Temperature: 31.52 C, Water level: 0, mfield: 1, Sound Level: 23
1/11/21 23:57:08, Temperature: 31.06 C, Water level: 0, mfield: 1, Sound Level: 17
1/11/21 23:57:09, Temperature: 30.60 C, Water level: 0, mfield: 1, Sound Level: 0
1/11/21 23:57:10, Temperature: 30.32 C, Water level: 0, mfield: 1, Sound Level: 27
1/11/21 23:57:11, Temperature: 29.86 C, Water level: 0, mfield: 1, Sound Level: 11
1/11/21 23:57:12, Temperature: 29.68 C, Water level: 0, mfield: 1, Sound Level: 12
1/11/21 23:57:13, Temperature: 29.50 C, Water level: 0, mfield: 1, Sound Level: 23
1/11/21 23:57:14, Temperature: 29.32 C, Water level: 0, mfield: 1, Sound Level: 26
This demonstration sketch shows that the MKR WiFi 1010 can be used to generate time stamped sensor data using the RTC and connect to the internet via WiFi. The next step is to connect it to the Arduino IoT Cloud so that the data can be monitored from anywhere.
The Sketch
The sketch is shown below.
/*
* This sketch modifies the WiFi RTC tutorial found at
* https://www.arduino.cc/en/Tutorial/WiFiRTC
* to make it more module and to correct the hours output
* when using negative GMT timezones.
* By Jay Morreale
* 1/10/2021
*
* MKR1000 - MKR WiFi 1010 - MKR VIDOR 4000 WiFi RTC
* This sketch asks NTP for the Linux epoch and sets the
* internal Arduino MKR1000's RTC accordingly.
* created 08 Jan 2016
* by Arturo Guadalupi <a.guadalupi@arduino.cc>
* modified 26 Sept 2018
* http://arduino.cc/en/Tutorial/WiFiRTC
* This code is in the public domain.
*
*/
#include <SPI.h>
#include <WiFiNINA.h>
#include <WiFiUdp.h>
#include <RTCZero.h>
#include "wifi_secrets.h"; // include the ssid and password
/*
* Digital sensor pin definitions
*/
#define HALL_SENSOR 0
#define WATER_SENSOR 1
#define LED_01 2
/*
* Analog sensor pin definitions
*/
#define pinTemp A0 // Define the pin to which the temperature sensor is connected.
#define pinSound A1 // Define the pins to which the sound sensor and LED are connected.
RTCZero rtc; // create an RTC object
/*
* Define WiFi variables
*/
char ssid[] = SECRET_SSID; // your network SSID (name)
char pass[] = SECRET_PASS; // your network password (use for WPA, or use as key for WEP)
int keyIndex = 0; // your network key Index number (needed only for WEP)
int status = WL_IDLE_STATUS; // define a variable for the wifi status
/*
* Define varialbles for calculationg local time for a given timezone.
*/
const int GMT = -5; // change this to adapt it to your timezone
int diff = 0; // difference between gmt hours and GMT
int tz = 0; // hours correct for GMT time zone when GMT < 0
int tzhours = 0; // used to hold the rtc.getHours value
/*
* Define variables for for the sensors
*/
int mfield = 0; // magnetic field read value
int wlevel = 0; // water level read value
const int B = 3975; // thermister coefficient b-value
int tempVal = 0; // thermister read value
float resistance = 0; // thermister resistance
float temperature = 0; // thermister temperature
int soundVal = 0; // sound lever read value
int soundThreshold = 4; // sound level threahold value
int soundSample = 0; // variable to hold the sound sample
/*
* Setup
*/
void setup() {
Serial.begin(115200); // setup the serial monitor at the specified baud rate
pinMode(HALL_SENSOR, INPUT);
pinMode(WATER_SENSOR, INPUT);
pinMode(pinTemp, INPUT);
pinMode(pinSound, INPUT);
pinMode(LED_01,OUTPUT);
checkWiFi(); // test to see that the WiFi module is working
connectWiFi(); // connect to the wifi network and wait until it connects
printWiFiStatus(); // print the status of the wifi network connection
rtc.begin(); // start the real time clock (RTC)
getNTPtime(); // setup the RTC by getting the epoch from the NTP server
}
/*
* Loop
*/
void loop() {
printDate(); // print the date as month, day, year
printTime(); // print the time in hours, minutes, seconds for the timezone
printTempSense(); // print the temperature
printWaterSense(); // print the water sensor output 0=wet
printMfieldSense(); // print the magnetic field sensor output 0=magnetic field
printSoundSense(); // print the output of the sound sensor
Serial.println();
delay(1000); // wait a 1000 ms before getting the next time
}
/*
* Function definitions
*/
/*
* Test the WiFi module works. Run once in setup()
*/
void checkWiFi() {
if (WiFi.status() == WL_NO_SHIELD) {
Serial.println("WiFi shield not present");
// don't continue:
while (true);
}
}
/*
* Setup the wifi module by attempting to connect to WiFi network. Run once in setup()
*/
void connectWiFi() {
while ( status != WL_CONNECTED) {
Serial.print("Attempting to connect to SSID: ");
Serial.println(ssid);
// Connect to WPA/WPA2 network. Change this line if using open or WEP network:
status = WiFi.begin(ssid, pass);
// wait 10 seconds for connection:
delay(10000);
}
}
/*
* Setup the RTC by getting the time form the NTP. Run once in setup()
*/
void getNTPtime() {
unsigned long epoch;
int numberOfTries = 0, maxTries = 6;
do {
epoch = WiFi.getTime();
numberOfTries++;
}
while ((epoch == 0) && (numberOfTries < maxTries));
if (numberOfTries == maxTries) {
Serial.print("NTP unreachable!!");
while (1);
} else {
Serial.print("Epoch received: ");
Serial.println(epoch);
rtc.setEpoch(epoch);
Serial.println();
}
}
/*
* Print the time
*/
void printTime() {
tzhours = gmtHour(rtc.getHours(), GMT);
print2digits(tzhours);
Serial.print(":");
print2digits(rtc.getMinutes());
Serial.print(":");
print2digits(rtc.getSeconds());
}
/*
* The original code to compute the time corrected for the users
* timezone does not work for negatve GMT values. gmtHour() calculates
* the correct hour assuming a 24 hour clock.
*/
int gmtHour(int hr, int gmt) {
diff = (hr + gmt);
if(diff < 0 ) {
tz = (24 + diff);
} else {
tz = diff;
}
return tz;
}
/*
* Print the date in month, day, year (mm/dd/yy) format
*/
void printDate() {
Serial.print(rtc.getMonth());
Serial.print("/");
Serial.print(rtc.getDay());
Serial.print("/");
Serial.print(rtc.getYear());
Serial.print(" ");
}
/*
* Print the WiFi status
*/
void printWiFiStatus() {
// print the SSID of the network you're attached to:
Serial.print("SSID: ");
Serial.println(WiFi.SSID());
// print your WiFi shield's IP address:
IPAddress ip = WiFi.localIP();
Serial.print("IP Address: ");
Serial.println(ip);
// print the received signal strength:
long rssi = WiFi.RSSI();
Serial.print("signal strength (RSSI):");
Serial.print(rssi);
Serial.println(" dBm");
}
/*
* Print a number with two digits
*/
void print2digits(int number) {
if (number < 10) {
Serial.print("0");
}
Serial.print(number);
}
/*
* Print the temperature
*/
void printTempSense() {
// Print the temperature to the serial console.
Serial.print(", Temperature: ");
Serial.print(sampleTemp());
Serial.print(" C, ");
}
/*
* Print the water sensor state
*/
void printWaterSense() {
Serial.print("Water level: ");
Serial.print(sampleWlevel());
}
/*
* Print the magnetic field sensor output 0=magnetic field present
*/
void printMfieldSense() {
Serial.print(", mfield: ");
Serial.print(sampleMfield());
}
/*
* Print the sound level
*/
void printSoundSense() {
Serial.print(", Sound Level: ");
Serial.print(soundSample = sampleSound());
setLED(soundSample, soundThreshold);
}
/*
* Sample the temperature
*/
float sampleTemp() {
// Read the temperature value
tempVal = analogRead(pinTemp);
// Determine the current resistance of the thermistor based on the sensor value.
resistance = (float)(1023-tempVal)*10000/tempVal;
// Calculate the temperature based on the resistance value in degrees Celsius.
temperature = 1/(log(resistance/10000)/B+1/298.15)-273.15;
return temperature;
}
/*
* Sample the sound level
*/
int sampleSound() {
//
soundVal = analogRead(pinSound);
return soundVal;
}
/*
* Sample the magnetic field
*/
int sampleMfield() {
// read magnetic field sensor
mfield = digitalRead(HALL_SENSOR);
return mfield;
}
/*
* Sample the water sensor
*/
int sampleWlevel() {
// read the water sensors
wlevel = digitalRead(WATER_SENSOR);
return wlevel;
}
/*
* Turn the LED on if s > th
*/
void setLED(int s, int th) {
if(s > th) {
digitalWrite(LED_01, HIGH);
} else {
digitalWrite(LED_01,LOW);
}
}
References
The following Tutorials were used to create this sketch.
- Getting started with the MKR WiFi 1010
- Connecting MKR WiFi 1010 to a Wi-Fi network
- Web Server using Access Point (AP) mode with MKR WiFi 1010
- Host a web server on the MKR WiFi 1010
- WiFi RTC
- Grove - LED Socket Kit
- Grove - Water Sensor
- Grove - Hall Sensor
- Grove - Temperature Sensor V1.2
- Arduino Libraries
- Arduino Language Reference