Schaake.nu

Utility Arduino

Gepost in /Motorboot op 16 April 2017
Deze blog is geschreven door Christiaan Schaake

Arduino Utility computer

In deel 1 en deel 2 heb ik uitgelegt hoe mijn boordcomputer netwerkje er uit moet komen te zien. Eén van de onderdelen is een Arduino Nano met een aantal sensoren. Deze Arduino meet onderandere buitenluchtdruk, temperatuur, luchtvochtigheid en de status van de licht accu. Van de licht accu meten we het voltage en de amperes via een shunt.

Buitenlucht

De buitenlucht luchtdruk, temperatuur en luchtvochtigheid worden gemeten met een 2-tal sensoren. Een BMP180 voor de buitenluchtdruk en een DHT11 voor de luchtvochtigheid. Biede sensoren geven ook de temperatuur door.

De BMP180 zit aangesloten op de I2C bus van de Arduino. Deze bus zit op pin A4 en A5. De sensor kan direct aangesloten worden op 5volt. De DHT11 zit aangesloten op pin D4 en heeft een eigen bus protocol. Voor beide sensoren wordt gebruik gemaakt van speciale libraries voor de Arduino. Hierdoor is het heel eenvoudig om de beide sensoren uit te lezen.

Accu

Van de licht accu willen we de accu spanning en de laad/ontlaad stroom weten. De accu spanning is relatief eenvoudig. De Arduino heeft een analoge ingang waarmee een waarde van 0 tot 5 volt gemeten kan worden. Dit refereert in een digitiale waarde van 0 tot 1023 in de software. Echter is een accu meer dan 14 volt (tijdens laden). Doormiddel van een eenvoudige 1:3 voltage devider wordt de spanning van 0 - 20 volt gemeten.
De stroom meten we via een shunt weerstand (in de massa van de accu aansluiting). Deze shunt meet 0 - 200 ampere. De spanning over de shunt is 0 - 100mV. Dit is te weinig om direct via de analoge ingang van de Arduino te meten. Hiervoor gebruiken we een versterker, de AD612AN.

In het schema is de AD612AN aangesloten op pin A1 van de Arduino. Over pin 1 en pin 2 van de AD612AN wordt een variabele weerstand geplaatst om de schakeling te kunnen compenseren. De voltage devider maakt gebruik van een 1Kohm en een 3 Kohm weerstand. De pin A0 van de Arduino is verbonden tussen de 2 weerstanden. De 12v aansluiting komt op de 3Kohm weerstand.

Hardware

Na testen met een breadboard heb ik alle componenten op een expirementeer printplaat gesoldeerd. Aan één zijde zitten alle aansluitingen van alle sensoren. De Arduino wordt via de USB aansluiting verbonden met de RaspBerry Pi.

De ruimte die over is op de printplaat kan gebruikt worden voor toekomstige sensoren. Mogelijk een ultrasoon afstandssensor voor de watertank en vuilwatertank. Of een extra temperatuur sensor voor de buitenwater temperatuur. De Arduino heeft nog ingangen genoeg over.

Software

Voor de BMP180 en de DHT11 maken we gebruik van de bijbehorende libraries. Beide libraries worden eerst geïnitialiseerd waarna ze in een loop worden uitgelezen. In dezelfde loop worden ook de 2 analoge poorten voor de accu spanning en stroom uitgelezen.
Alle waarden worden via de USB poort serieel doorgegeven aan de RaspBerry Pi. Hiervoor maak ik gebruik van een eigen uitbereiding op het NMEA protocol. Er zijn 3 functies geschreven in de software. De eerste schrijft een NMEA regel weg naar de seriele poort en maakt daarbij gebruik van een 2e functie welke de hashcode aan het einde van de NMEA regel berekend. De 3e functie berekend het dauwpunt. Deze wordt meegegeven bij de luchtvochtigheids regel.
De interne led (pin 13) gebruik ik om aan te geven dat het programma loopt door de led aan te schakelen, tijdens het wachten op de volgende loop gaat de led uit.

// Libraries for BMP180 #include "SFE_BMP180.h" // Libraries voor DHT11 #include "DHT.h" // Create BMP180 object called pressure SFE_BMP180 bmp180; // Create DHT11 object called dht DHT dht; // Setup arduino void setup() { // Set program run led on internal led on pin 13 pinMode(13, OUTPUT); // Open serial port Serial.begin(9600); // Initialize the BMP180 sensor Device is connected to pins A4 and A5. if (bmp180.begin()) Serial.println("BMP180 init success"); else { Serial.println("BMP180 init fail\n\n"); while(1); // Pause forever. } // Initialize the DHT11 sensor on D4 dht.setup(4); } // Application loop void loop() { // Turn internal led on digitalWrite(13, HIGH); char status; double temperature, pressure, humidity, dewpoint; // Get tempeture of BMP180, is required for correct pressure status = bmp180.startTemperature(); if (status != 0) { // Wait for the measurement to complete: delay(status); status = bmp180.getTemperature(temperature); if (status != 0) { // Print out the measurement: String nmea_temperature = "IIMTA,"; nmea_temperature = nmea_temperature + temperature; nmea_temperature = nmea_temperature + ",C"; nmea_print(nmea_temperature); status = bmp180.startPressure(3); if (status != 0) { // Wait for the measurement to complete: delay(status); status = bmp180.getPressure(pressure,temperature); if (status != 0) { // Print out the measurement: String nmea_barometer = "IIMMB,"; nmea_barometer = nmea_barometer + pressure * 0.0295333727,2; nmea_barometer = nmea_barometer + ",I,"; nmea_barometer = nmea_barometer + pressure; nmea_barometer = nmea_barometer + ",B"; nmea_print(nmea_barometer); } else Serial.println("error retrieving pressure measurement\n"); } else Serial.println("error starting pressure measurement\n"); } else Serial.println("error retrieving temperature measurement\n"); } else Serial.println("error starting temperature measurement\n"); // Wait for DHT to complete measure delay(dht.getMinimumSamplingPeriod()); // Get humidity and temperature humidity = dht.getHumidity(); temperature = dht.getTemperature(); dewpoint = dewPointFast(temperature, humidity); String nmea_humidity = "IIMHU,,"; nmea_humidity = nmea_humidity + humidity; nmea_humidity = nmea_humidity + ","; nmea_humidity = nmea_humidity + dewpoint; nmea_humidity = nmea_humidity + ",C"; nmea_print(nmea_humidity); // Turn internal led off digitalWrite(13, LOW); // Digital voltage and amps int voltSensor = analogRead(A0); int ampSensor = analogRead(A0); float voltage = voltSensor / 51.15; float amps = ampSensor / 5.115; String nmea_voltage = "IIUVA,"; nmea_voltage = nmea_voltage + voltage; nmea_voltage = nmea_voltage + ",V,"; nmea_voltage = nmea_voltage + amps; nmea_voltage = nmea_voltage + ",A"; nmea_print(nmea_voltage); // Pause for 5 seconds. delay(5000); } // Checksum calculation function char checkSum(String theseChars) { char check = 0; // iterate over the string, XOR each byte with the total sum: for (int c = 0; c < theseChars.length(); c++) { check = char(check ^ theseChars.charAt(c)); } // return the result return check; } void nmea_print(String nmea_command) { // Calculate checksum for nmea_command byte checksum = checkSum(nmea_command); Serial.print("$"); Serial.print(nmea_command); Serial.print("*"); Serial.println(checksum, HEX); } double dewPointFast(double celsius, double humidity) { double a = 17.271; double b = 237.7; double temp = (a * celsius) / (b + celsius) + log(humidity * 0.01); double Td = (b * temp) / (a - temp); return Td; }

De Arduino loopt door de loop en print telkens de sensor waarde naar de seriele poort.

$IIMTA,21.85,C*3B $IIMMB,30.05,I,1017.37,B*4C $IIMHU,,27.00,0.43,C*21 $IIUVA,12.21,V,0.23,A*55

De eerste regel met de MTA string geeft de temperatuur aan in graden celcius.
De tweede regel met MMB geeft de luchtdruk, de eerste waarde is de luchtdruk in inches, de tweede waarde de luchtdruk in mBar.
De derder regel met MHU geeft de luchtvochtigheid, eerste waarde is luchtvochtigheid in procent en de tweede waarde de dauwpunt temperatuur.
De laatste regel met UVA geeft de spanning en stroom weer van de utility accu.

Deze blog is getagd als AD612AN Arduino BMP180 Boordcomputer DHT11 NMEA Voltage devider

Google
facebook