Industriële fabricage
Industrieel internet der dingen | Industriële materialen | Onderhoud en reparatie van apparatuur | Industriële programmering |
home  MfgRobots >> Industriële fabricage >  >> Manufacturing Technology >> Productieproces

Compact Weerstation: Arduino Nano & ESP8266 Met BMP280 Barometrische Sensor & OLED/Nokia LCD Display

Onderdelen en benodigdheden

Compact Weerstation: Arduino Nano & ESP8266 Met BMP280 Barometrische Sensor & OLED/Nokia LCD Display
Arduino Nano R3
× 1
Compact Weerstation: Arduino Nano & ESP8266 Met BMP280 Barometrische Sensor & OLED/Nokia LCD Display
MyOctopus i2c Barometrische Luchtdruk Sensor BMP280
× 1
Nokia 5110 LCD
× 1
NodeMCU 1.0
× 1
Compact Weerstation: Arduino Nano & ESP8266 Met BMP280 Barometrische Sensor & OLED/Nokia LCD Display
Grafische OLED, 128 x 64
× 1

Nodige tools en machines

Compact Weerstation: Arduino Nano & ESP8266 Met BMP280 Barometrische Sensor & OLED/Nokia LCD Display
Soldeerbout (generiek)

Over dit project

Dit apparaat bestaat uit twee onafhankelijke modules in één behuizing.

Een is de Arduino barometer met de BMP180 sensor, die een rapport bevat van realtime, -1u en -3u verschil in luchtverontreiniging. Deze rapporten zijn met name nuttig in de korte termijn lokale weersvoorspelling. De code is afkomstig van de "shelvin.de" website, waarin het verschil tussen de absolute en de relatieve luchtdruk voor de gegeven hoogte in de "druck_offset=" regel in de code is ingevoerd. De resultaten worden gepresenteerd op het N5110 LCD-scherm, dat ook de interne temperatuur toont.

Compact Weerstation: Arduino Nano & ESP8266 Met BMP280 Barometrische Sensor & OLED/Nokia LCD Display

Het volgende apparaat wordt aangedreven door een ESP8266-bord dat een 0,96 inch OLED-display verbindt. De ESP8266 is via Wi-Fi-netwerk verbonden met de "openweathermap" pagina, waarvandaan het een drie-daagse weersvoorspelling haalt en presenteert op het OLED-display. Hiervoor heeft u een API-sleutel in de code nodig, die verkregen wordt van de Openweathermap-pagina. Volledige gedetailleerde instructies voor het installeren van bibliotheken en code op esp8266 zijn gegeven op:

https://blog.squix.org/wp-content/uploads/2017/06/esp8266weatherstationgettingstartedguide-20170608.pdf

In dit specifieke geval gebruik ik het NodeMCU 1.0 (ESP12E module) bord.

De afbeelding hieronder toont het schema van het complete apparaat.

Code

  • Ontitelde bestand
Ontitelde bestandArduino
// Luchtdruk Uitvoer huidig
// Luchtdrukdifferentiel wordt met 1 en 3 uur eerder (in EEPROM) vergeleken en uitgegeven
// Temperatuur Uitvoer huidig
//
// Onderdelen:
// LCD Display van Nokia 5110
// BMP180 Luchtdruksensor
// Arduino Uno
//
// Matthias Busse Versie 1.0 van 21.9.2014
#include < Wire.h>
#include < avr/sleep.h>
#include < EEPROM.h>
// EEPROM Variabelen
int eepromAdresse=0, eepromMax=1023; // 1024 EEPROM Opslagplaatsen, 0-1023
int eepromOldAdr, eepromDif1=60, eepromDif3=180; // 60/180 Opslagplaatsen (Minuten) terug vergelijken
// BMP180 Variabelen
#define I2C_ADDRESS 0x77
const unsigned char oversampling_setting = 3; //oversamplig: 0 onnauwkeurig (13ms) ... 3 nauwkeurig (34ms)
const unsigned char pressure_waittime[4] = { 5, 8, 14, 26 }; // lt. Datenblatt BMP-180
int ac1, ac2, ac3, b1, b2, mb, mc, md;
unsigned int ac4, ac5, ac6;
int temp = 20, temp_mittel=200, test=0;
long druck = 1013, druck_mittel=101300;
float t, temp_offset=0.0, d, dAlt, dDiff, druck_offset=2.0;
int zeitabgl=0, mitteln=5;
char tstring[5], dstring[7];
// Power Down Variabelen
volatile int sleepcounter = 0; // Slaapcycli tellen
// Display Variabelen
static const byte ASCII[][5] = {// ASCII Tabel met Fonts
{0x00, 0x00, 0x00, 0x00, 0x00} // 20
,{0x00, 0x00, 0x5f, 0x00, 0x00} // 21 !
,{0x00, 0x07, 0x00, 0x07, 0x00} // 22 "
,{0x14, 0x7f, 0x14, 0x7f, 0x14} // 23 #
,{0x24, 0x2a, 0x7f, 0x2a, 0x12} // 24 $
,{0x23, 0x13, 0x08, 0x64, 0x62} // 25 %
,{0x36, 0x49, 0x55, 0x22, 0x50} // 26 &
,{0x00, 0x05, 0x03, 0x00, 0x00} // 27 '
,{0x00, 0x1c, 0x22, 0x41, 0x00} // 28 (
,{0x00, 0x41, 0x22, 0x1c, 0x00} // 29 )
,{0x14, 0x08, 0x3e, 0x08, 0x14} // 2a *
,{0x08, 0x08, 0x3e, 0x08, 0x08} // 2b +
,{0x00, 0x50, 0x30, 0x00, 0x00} // 2c ,
,{0x08, 0x08, 0x08, 0x08, 0x08} // 2d -
,{0x00, 0x60, 0x60, 0x00, 0x00} // 2e .
,{0x20, 0x10, 0x08, 0x04, 0x02} // 2f /
,{0x3e, 0x51, 0x49, 0x45, 0x3e} // 30 0
,{0x00, 0x42, 0x7f, 0x40, 0x00} // 31 1
,{0x42, 0x61, 0x51, 0x49, 0x46} // 32 2
,{0x21, 0x41, 0x45, 0x4b, 0x31} // 33 3
,{0x18, 0x14, 0x12, 0x7f, 0x10} // 34 4
,{0x27, 0x45, 0x45, 0x45, 0x39} // 35 5
,{0x3c, 0x4a, 0x49, 0x49, 0x30} // 36 6
,{0x01, 0x71, 0x09, 0x05, 0x03} // 37 7
,{0x36, 0x49, 0x49, 0x49, 0x36} // 38 8
,{0x06, 0x49, 0x49, 0x29, 0x1e} // 39 9
,{0x00, 0x36, 0x36, 0x00, 0x00} // 3a :
,{0x00, 0x56, 0x36, 0x00, 0x00} // 3b ;
,{0x08, 0x14, 0x22, 0x41, 0x00} // 3c <
,{0x14, 0x14, 0x14, 0x14, 0x14} // 3d =
,{0x00, 0x41, 0x22, 0x14, 0x08} // 3e >
,{0x02, 0x01, 0x51, 0x09, 0x06} // 3f ?
,{0x32, 0x49, 0x79, 0x41, 0x3e} // 40 @
,{0x7e, 0x11, 0x11, 0x11, 0x7e} // 41 A
,{0x7f, 0x49, 0x49, 0x49, 0x36} // 42 B
,{0x3e, 0x41, 0x41, 0x41, 0x22} // 43 C
,{0x7f, 0x41, 0x41, 0x22, 0x1c} // 44 D
,{0x7f, 0x49, 0x49, 0x49, 0x41} // 45 E
,{0x7f, 0x09, 0x09, 0x09, 0x01} // 46 F
,{0x3e, 0x41, 0x49, 0x49, 0x7a} // 47 G
,{0x7f, 0x08, 0x08, 0x08, 0x7f} // 48 H
,{0x00, 0x41, 0x7f, 0x41, 0x00} // 49 I
,{0x20, 0x40, 0x41, 0x3f, 0x01} // 4a J
,{0x7f, 0x08, 0x14, 0x22, 0x41} // 4b K
,{0x7f, 0x40, 0x40, 0x40, 0x40} // 4c L
,{0x7f, 0x02, 0x0c, 0x02, 0x7f} // 4d M
,{0x7f, 0x04, 0x08, 0x10, 0x7f} // 4e N
,{0x3e, 0x41, 0x41, 0x41, 0x3e} // 4f O
,{0x7f, 0x09, 0x09, 0x09, 0x06} // 50 P
,{0x3e, 0x41, 0x51, 0x21, 0x5e} // 51 Q
,{0x7f, 0x09, 0x19, 0x29, 0x46} // 52 R
,{0x46, 0x49, 0x49, 0x49, 0x31} // 53 S
,{0x01, 0x01, 0x7f, 0x01, 0x01} // 54 T
,{0x3f, 0x40, 0x40, 0x40, 0x3f} // 55 U
,{0x1f, 0x20, 0x40, 0x20, 0x1f} // 56 V
,{0x3f, 0x40, 0x38, 0x40, 0x3f} // 57 W
,{0x63, 0x14, 0x08, 0x14, 0x63} // 58 X
,{0x07, 0x08, 0x70, 0x08, 0x07} // 59 Y
,{0x61, 0x51, 0x49, 0x45, 0x43} // 5a Z
,{0x00, 0x7f, 0x41, 0x41, 0x00} // 5b [
,{0x02, 0x04, 0x08, 0x10, 0x20} // 5c ?
,{0x00, 0x41, 0x41, 0x7f, 0x00} // 5d ]
,{0x04, 0x02, 0x01, 0x02, 0x04} // 5e ^
,{0x40, 0x40, 0x40, 0x40, 0x40} // 5f _
,{0x00, 0x01, 0x02, 0x04, 0x00} // 60 `
,{0x20, 0x54, 0x54, 0x54, 0x78} // 61 a
,{0x7f, 0x48, 0x44, 0x44, 0x38} // 62 b
,{0x38, 0x44, 0x44, 0x44, 0x20} // 63 c
,{0x38, 0x44, 0x44, 0x48, 0x7f} // 64 d
,{0x38, 0x54, 0x54, 0x54, 0x18} // 65 e
,{0x08, 0x7e, 0x09, 0x01, 0x02} // 66 f
,{0x0c, 0x52, 0x52, 0x52, 0x3e} // 67 g
,{0x7f, 0x08, 0x04, 0x04, 0x78} // 68 h
,{0x00, 0x44, 0x7d, 0x40, 0x00} // 69 i
,{0x20, 0x40, 0x44, 0x3d, 0x00} // 6a j
,{0x7f, 0x10, 0x28, 0x44, 0x00} // 6b k
,{0x00, 0x41, 0x7f, 0x40, 0x00} // 6c l
,{0x7c, 0x04, 0x18, 0x02, 0x7f} // 6d m
,{0x7c, 0x08, 0x04, 0x04, 0x78} // 6e n
,{0x38, 0x44, 0x44, 0x44, 0x38} // 6f o
,{0x7c, 0x14, 0x14, 0x14, 0x08} // 70 p
,{0x08, 0x14, 0x14, 0x18, 0x7c} // 71 q
,{0x7c, 0x08, 0x04, 0x04, 0x08} // 72 r
,{0x48, 0x54, 0x54, 0x54, 0x20} // 73 s
,{0x04, 0x3f, 0x44, 0x40, 0x20} // 74 t
,{0x3c, 0x40, 0x40, 0x20, 0x7c} // 75 u
,{0x1c, 0x20, 0x40, 0x20, 0x1c} // 76 v
,{0x3c, 0x40, 0x30, 0x40, 0x3c} // 77 w
,{0x44, 0x28, 0x10, 0x28, 0x44} // 78 x
,{0x0c, 0x50, 0x50, 0x50, 0x3c} // 79 y
,{0x44, 0x64, 0x54, 0x4c, 0x44} // 7a z
,{0x00, 0x08, 0x36, 0x41, 0x00} // 7b {
,{0x00, 0x00, 0x7f, 0x00, 0x00} // 7c |
,{0x00, 0x41, 0x36, 0x08, 0x00} // 7d }
,{0x10, 0x08, 0x08, 0x10, 0x08} // 7e <
,{0x78, 0x46, 0x41, 0x46, 0x78} // 7f >
};
#define RST 12
#define CE 11
#define DC 10
#define DIN 9
#define CLK 8
void setup(){
  for(int i=0; i < eepromMax; i+=4) // EEPROM alles naar nul
    eepromWriteLong(0,i);
  // Power Down Instellingen
  watchdogOn(); // Watchdog timer inschakelen.
  ADCSRA = ADCSRA & B01111111; // ADC uitschakelen, ADEN bit7 naar 0
  ACSR = B10000000; // Analoge Comparator uitschakelen, ACD bit7 naar 1
  DIDR0 = DIDR0 | B00111111; // Digitale ingang buffers uitschakelen, analoge ingang pinnen 0-5 op 1
  Wire.begin(); // BMP180 Instellingen
  bmp180_get_cal_data();
  bmp180_read_temperature_and_pressure(&temp_mittel,&druck_mittel); // eerst gemiddelden lezen
  pinMode(RST, OUTPUT); // 5110 Display Instellingen
  pinMode(CE, OUTPUT);
  pinMode(DC, OUTPUT);
  pinMode(DIN, OUTPUT);
  pinMode(CLK, OUTPUT);
  digitalWrite(RST, LOW);
  digitalWrite(RST, HIGH);
  LcdWriteCmd(0x21); // LCD extended commands
  LcdWriteCmd(0xB8); // set LCD Vop (contrast)
  LcdWriteCmd(0x04); // set temp coefficent
  LcdWriteCmd(0x14); // LCD bias mode 1:40
  LcdWriteCmd(0x20); // LCD basic commands
  LcdWriteCmd(0x0C); // LCD normal video
  LcdClearScreen();
}
void loop() {
  bmp180_read_temperature_and_pressure(&temp, &druck); // duurt ca. 51ms
  temp_mittel = ((temp_mittel * (mitteln-1)) + temp) / mitteln;
  druck_mittel = ((druck_mittel * (mitteln-1)) + druck) / mitteln;
  t=((float)temp_mittel/10.0)+temp_offset;
  d=((float)druck_mittel/100.0)+druck_offset;
  LcdClearLine(0);
  LcdXY(12,0);
  LcdWriteString(dtostrf(d,7,2,dstring));
  LcdXY(60,0);
  LcdWriteString("hPa");
  eepromWriteLong(d*100, eepromAdresse); // Druk in EEPROM opslaan met 2 decimalen (*100 long)
  eepromOldAdr=eepromAdresse -(eepromDif1*4); // Diff 1u terug gaan
  if(eepromOldAdr < 0) eepromOldAdr = eepromMax + 1 + eepromOldAdr; // overflow
  dAlt=(float)eepromReadLong(eepromOldAdr)/100.0; // oude waarde lezen
  dDiff=d-dAlt; // Differentie vormen
  LcdClearLine(2);
  LcdXY(8,2); // Uitgeven
  LcdWriteString("1u:");
  if(dAlt > 800) {
    LcdXY(27,2);
    if(dDiff < 0.0) LcdWriteString("-");
    else LcdWriteString("+");
    if(dDiff < 0.0) dDiff=dDiff*-1.0; // Absoluutwaarde
    LcdXY(34,2);
    LcdWriteString(dtostrf(dDiff,4,2,dstring));
  }
  LcdXY(60,2);
  LcdWriteString("hPa");
  eepromOldAdr=eepromAdresse -(eepromDif3*4); // Diff 3u terug gaan
  if(eepromOldAdr < 0) eepromOldAdr = eepromMax + 1 + eepromOldAdr; // overflow
  dAlt=(float)eepromReadLong(eepromOldAdr)/100.0; // oude waarde lezen
  dDiff=d-dAlt; // Differentie vormen
  LcdClearLine(3);
  LcdXY(8,3); // Uitgeven
  LcdWriteString("3u:");
  if(dAlt > 800) {
    LcdXY(27,3);
    if(dDiff < 0.0) LcdWriteString("-");
    else LcdWriteString("+");
    if(dDiff < 0.0) dDiff=dDiff*-1.0; // Absoluutwaarde
    LcdXY(34,3);
    LcdWriteString(dtostrf(dDiff,4,2,dstring));
  }
  LcdXY(60,3);
  LcdWriteString("hPa");
  LcdClearLine(5); // Temperatuur uitgeven
  LcdXY(8,5);
  LcdWriteString("Temp. ");
  LcdXY(43,5);
  LcdWriteString(dtostrf(t,4,1,tstring));
  LcdXY(73,5);
  LcdWriteString("C");
  eepromAdresse += 4;
  if(eepromAdresse > eepromMax) eepromAdresse=0;
  pwrDown(54); // ATmega328 gaat naar beneden voor de rest van de 60 seconden
}
void eepromWriteLong(long lo, int adr) {
// long waarde in het EEPROM schrijven
// Invoer : adr Opslagplaats
// Invoer : lo Getal, Waardenbereik -2.147.483.648 tot 2.147.483.647
//
// Matthias Busse 23.5.2014 Versie 1.0
byte by;
for(int i=0;i < 4;i++) {
  by = (lo >> ((3-i)*8)) & 0x000000ff;
  EEPROM.write(adr+i, by);
}
}
// eepromWriteLong
long eepromReadLong(int adr) {
// long int waarde uit 4 Byte EEPROM lezen
// Invoer : adr tot adr+3
// Uitvoer : long Waarde
//
// Matthias Busse 23.5.2014 Versie 1.0
long lo=0;
for(int i=0;i < 3;i++) {
  lo += EEPROM.read(adr+i);
  lo = lo << 8;
}
lo += EEPROM.read(adr+3);
return lo;
}
// eepromReadLong
void LcdWriteString(char *characters) {
// String uitvoeren
while(*characters) LcdWriteCharacter(*characters++);
}
void LcdWriteCharacter(char character) {
// ASCII teken uitvoeren uit tabel boven
for(int i=0; i < 5; i++) LcdWriteData(ASCII[character - 0x20][i]);
LcdWriteData(0x00);
}
void LcdWriteCmd(byte cmd){
// Commando naar display sturen
digitalWrite(DC, LOW); //DC pin is laag voor commando's
digitalWrite(CE, LOW);
shiftOut(DIN, CLK, MSBFIRST, cmd); // seriële data transmitteren
digitalWrite(CE, HIGH);
}
void LcdWriteData(byte cmd){
// Data naar display sturen
digitalWrite(DC, HIGH); //DC pin is hoog voor data
digitalWrite(CE, LOW);
shiftOut(DIN, CLK, MSBFIRST, cmd); // seriële data transmitteren
digitalWrite(CE, HIGH);
}
void LcdClearScreen() {
// Scherm leegmaken
for(int i=0; i < 504; i++) LcdWriteData(0x00);
}
void LcdClearLine(int line) {
// Regel leegmaken
LcdXY(0, line);
for(int i=0; i < 84; i++) LcdWriteData(0x00);
}
void LcdXY(int x, int y) {
// Naar X / Y Positie gaan
LcdWriteCmd(0x80|x); // Kolom
LcdWriteCmd(0x40|y); // Rij
}
void bmp180_read_temperature_and_pressure(int* temp, long* druck) {
  int ut= bmp180_read_ut();
  long up = bmp180_read_up();
  long x1, x2, x3, b3, b5, b6, p;
  unsigned long b4, b7;
  x1 = ((long)ut - ac6) * ac5 >> 15; //Temperatuur berekenen
  x2 = ((long) mc << 11) / (x1 + md);
  b5 = x1 + x2;
  *temp = (b5 + 8) >> 4;
  b6 = b5 - 4000; //Druk berekenen
  x1 = (b2 * (b6 * b6 >> 12)) >> 11;
  x2 = ac2 * b6 >> 11;
  x3 = x1 + x2;
  if (oversampling_setting == 3) b3 = ((int32_t) ac1 * 4 + x3 + 2) << 1;
  if (oversampling_setting == 2) b3 = ((int32_t) ac1 * 4 + x3 + 2);
  if (oversampling_setting == 1) b3 = ((int32_t) ac1 * 4 + x3 + 2) >> 1;
  if (oversampling_setting == 0) b3 = ((int32_t) ac1 * 4 + x3 + 2) >> 2;
  x1 = ac3 * b6 >> 13;
  x2 = (b1 * (b6 * b6 >> 12)) >> 16;
  x3 = ((x1 + x2) + 2) >> 2;
  b4 = (ac4 * (uint32_t) (x3 + 32768)) >> 15;
  b7 = ((uint32_t) up - b3) * (50000 >> oversampling_setting);
  p = b7 < 0x80000000 ? (b7 * 2) / b4 : (b7 / b4) * 2;
  x1 = (p >> 8) * (p >> 8);
  x1 = (x1 * 3038) >> 16;
  x2 = (-7357 * p) >> 16;
  *druck = p + ((x1 + x2 + 3791) >> 4);
}
unsigned int bmp180_read_ut() {
  write_register(0xf4,0x2e);
  delay(5); // meer dan 4.5 ms
  return read_int_register(0xf6);
}
void bmp180_get_cal_data() {
  ac1 = read_int_register(0xAA);
  ac2 = read_int_register(0xAC);
  ac3 = read_int_register(0xAE);
  ac4 = read_int_register(0xB0);
  ac5 = read_int_register(0xB2);
  ac6 = read_int_register(0xB4);
  b1 = read_int_register(0xB6);
  b2 = read_int_register(0xB8);
  mb = read_int_register(0xBA);
  mc = read_int_register(0xBC);
  md = read_int_register(0xBE);
}
long bmp180_read_up() {
  write_register(0xf4,0x34+(oversampling_setting<<6));
  delay(pressure_waittime[oversampling_setting]);
  unsigned char msb, lsb, xlsb;
  Wire.beginTransmission(I2C_ADDRESS);
  Wire.write(0xf6);
  Wire.endTransmission();
  Wire.requestFrom(I2C_ADDRESS, 3);
  while(!Wire.available()) {} // wachten
  msb = Wire.read();
  while(!Wire.available()) {} // wachten
  lsb |= Wire.read();
  while(!Wire.available()) {} // wachten
  xlsb |= Wire.read();
  return (((long)msb<<16) | ((long)lsb<<8) | ((long)xlsb)) >>(8-oversampling_setting);
}
void write_register(unsigned char r, unsigned char v) {
  Wire.beginTransmission(I2C_ADDRESS);
  Wire.write(r);
  Wire.write(v);
  Wire.endTransmission();
}
char read_register(unsigned char r) {
  unsigned char v;
  Wire.beginTransmission(I2C_ADDRESS);
  Wire.write(r);
  Wire.endTransmission();
  Wire.requestFrom(I2C_ADDRESS, 1);
  while(!Wire.available()) {} // wachten
  v = Wire.read();
  return v;
}
int read_int_register(unsigned char r) {
  unsigned char msb, lsb;
  Wire.beginTransmission(I2C_ADDRESS);
  Wire.write(r);
  Wire.endTransmission();
  Wire.requestFrom(I2C_ADDRESS, 2);
  while(!Wire.available()) {} // wachten
  msb = Wire.read();
  while(!Wire.available()) {} // wachten
  lsb = Wire.read();
  return (((int)msb<<8) | ((int)lsb));
}
void pwrDown(int sekunden) {
  set_sleep_mode(SLEEP_MODE_PWR_DOWN); // de diepste slaap selecteren PWR_DOWN
  for(int i=0; i < sekunden; i++) {
    sleep_enable(); // sleep mode inschakelen
    sleep_mode(); // in de sleep mode gaan
    sleep_disable(); // sleep mode uitschakelen na het ontwaken
  }
}
void watchdogOn() {
  MCUSR = MCUSR & B11110111; // Reset vlag uitschakelen, WDRF bit3 van MCUSR.
  WDTCSR = WDTCSR | B00011000; // Bit 3+4 om daarna de Prescaler te kunnen zetten
  WDTCSR = B00000110; // Watchdog Prescaler op 128k zetten > resulteert in ca. 1 seconde
  WDTCSR = WDTCSR | B01000000; // Watchdog Interrupt inschakelen
  MCUSR = MCUSR & B11110111;
}
ISR(WDT_vect) {
  sleepcounter ++; // Slaapcycli tellen
}

Schema's

Compact Weerstation: Arduino Nano & ESP8266 Met BMP280 Barometrische Sensor & OLED/Nokia LCD Display

Productieproces

  1. De Kazoo: Van Oude Mirliton tot Modern Plastic Speelgoed – Geschiedenis, Productie & Toekomst
  2. Giftduino: De Ultieme Arduino Cadeau-set voor Hobbyisten en Docenten
  3. BME280 Temperatuur, Vochtigheid & Druk Weergeven op Nextion Touchscreen
  4. High-Performance Arduino Weerballon Datalogger
  5. Bouw een $10 Draagbare Arduino Weerstation (AWS) – Eenvoudige DIY met Nano, DHT22, BMP180 & LCD
  6. eDOT: Precieze Arduino-klok & weerstation met ingebouwde IR-remote
  7. Realtime Weerstation met Arduino & ThingSpeak IoT
  8. Real-Time IoT Drukmonitoring met MKR GSM, Arduino Cloud en Google Sheets
  9. Bouw een betrouwbare Arduino-weerstation met DHT-sensoren
  10. Bouw een Arduino-aangedreven LEGO Arcade Game Box – DIY Kit met Nano, Batterij, LCD en Meer
  11. Jumper Wires Elimineren: Hoe BreadShield Arduino Direct Met Breadboards Verbindt