Anyone got an Arduino boat project to swap?

Poey50

Well-Known Member
Joined
26 Apr 2016
Messages
2,319
Location
Chichester
Visit site
Long separation from the boat calls for desperate measures in finding new time-consuming but cheap projects. So Arduino-nerds, what have you got?

Here's the first of mine - two voltage sensors, four relays and a temperature and humidity sensor to communicate by text with the boat from 100 miles away. Total cost under £40 plus £6 per month for a SIM card.

This page introduces the use of the SIM900. In-Depth: Send Receive SMS & Call with SIM900 GSM Shield & Arduino

7LvsB84l.png



Screenshot from my mobile phone
S2t8pS2l.jpg



Code
#include <SoftwareSerial.h> // Library for using serial communication
SoftwareSerial SIM900(7, 8); // Pins 7, 8 are used as used as software serial pins

// Temp and humidity parameters
#include "DHT.h"
#define DHTPIN 2 // Digital pin connected to the DHT sensor
#define DHTTYPE DHT22 // DHT 22
DHT dht(DHTPIN, DHTTYPE);
float h;
float t;

// GSM parameters
String incomingData; // for storing incoming serial data
String message = ""; // A string for storing the message
int relay_pin1 = 3; // Initialized a pin for relay module
int relay_pin2 = 4; // Initialized a pin for relay module
int relay_pin3 = 5; // Initialized a pin for relay module
int relay_pin4 = 6; // Initialized a pin for relay module

// Voltmeter code parameters
int analogInput1 = A1;
int analogInput2 = A0;
float vout1 = 0.0;
float vout2 = 0.0;
float vin1 = 0.0;
float vin2 = 0.0;
float R1 = 30000.0; //
float R2 = 7500.0; //
int value = 0;
String Voltstring = "";

void setup()
{
SIM900.begin(9600);
Serial.println("Power on");
Serial.begin(9600);
SIM900power();
delay(20000); // give time to log on to network.

// GSM setup

dht.begin();

// Temp and humidity sensor setup (using GSM baudrate of 115200)


// GSM setup 2

pinMode(relay_pin1, OUTPUT); // Setting relay pin as output pin
digitalWrite(relay_pin1, LOW); // Making relay pin initailly low
pinMode(relay_pin2, OUTPUT); // Setting relay pin as output pin
digitalWrite(relay_pin2, LOW); // Making relay pin initailly low
pinMode(relay_pin3, OUTPUT); // Setting relay pin as output pin
digitalWrite(relay_pin3, LOW); // Making relay pin initailly low
pinMode(relay_pin4, OUTPUT); // Setting relay pin as output pin
digitalWrite(relay_pin4, LOW); // Making relay pin initailly low

// set SMS mode to text mode
SIM900.print("AT+CMGF=1\r");
delay(100);

// set gsm module to tp show the output on serial out
SIM900.print("AT+CNMI=2,2,0,0,0\r");
delay(100);

// Voltmeter code setup

pinMode(analogInput1, INPUT);
pinMode(analogInput2, INPUT);
Serial.begin(9600);
Serial.print("DC VOLTMETER");

}

//Insert soft start code here
void SIM900power()
{
pinMode(9, OUTPUT);
digitalWrite(9, LOW);
delay(1000);
digitalWrite(9, HIGH);
delay(2000);
digitalWrite(9, LOW);
delay(3000);
}
// End of soft start code

void loop()
{
//Function for receiving sms
receive_message();

// Read temperature as Celsius (the default)
t = dht.readTemperature();

// if received command is to turn off relay
if (incomingData.indexOf("Hoff") >= 0)
{
digitalWrite(relay_pin1, LOW);
message = "House is turned OFF";
// Send a sms back to confirm that the relay is turned off
send_message(message);
}

// if received command is to turn on relay
if (incomingData.indexOf("Hon") >= 0)
{
digitalWrite(relay_pin1, HIGH);
message = "House is turned ON";
// Send a sms back to confirm that the relay is turned on
send_message(message);
}

// if received command is to turn off relay
if (incomingData.indexOf("Soff") >= 0)
{
digitalWrite(relay_pin2, LOW);
message = "Start is turned OFF";
// Send a sms back to confirm that the relay is turned off
send_message(message);
}

// if received command is to turn on relay
if (incomingData.indexOf("Son") >= 0)
{
digitalWrite(relay_pin2, HIGH);
message = "Start is turned ON";
// Send a sms back to confirm that the relay is turned off
send_message(message);
}

// if received command is to turn off relay
if (incomingData.indexOf("3off") >= 0)
{
digitalWrite(relay_pin3, LOW);
message = "3 is turned OFF";
// Send a sms back to confirm that the relay is turned off
send_message(message);
}

// if received command is to turn on relay
if (incomingData.indexOf("3on") >= 0)
{
digitalWrite(relay_pin3, HIGH);
message = "3 is turned ON";
// Send a sms back to confirm that the relay is turned on
send_message(message);
}

// if received command is to turn off relay
if (incomingData.indexOf("4off") >= 0)
{
digitalWrite(relay_pin4, LOW);
message = "4 is turned OFF";
// Send a sms back to confirm that the relay is turned off
send_message(message);
}

// if received command is to turn on relay
if (incomingData.indexOf("4on") >= 0)
{
digitalWrite(relay_pin4, HIGH);
message = "4 is turned ON";
// Send a sms back to confirm that the relay is turned off
send_message(message);
}
// if received command is to read Voltage1
if (incomingData.indexOf("HV") >= 0)
{

// read the value at analog input
value = analogRead(analogInput1);
vout1 = (value * 5.0) / 1024.0; // see text
vin1 = (vout1 * 0.828) / (R2 / (R1 + R2));
Voltstring = String(vin1);
message = "House = " + Voltstring + "V";
// Send a sms stating the voltage measurement
send_message(message);

}
// if received command is to read Voltage2
if (incomingData.indexOf("SV") >= 0)
{

// read the value at analog input
value = analogRead(analogInput2);
vout2 = (value * 5.0) / 1024.0; // see text
vin2 = (vout2 * 0.828) / (R2 / (R1 + R2));
Voltstring = String(vin2);
message = "Start = " + Voltstring + "V";
// Send a sms stating the voltage measurement
send_message(message);
}

// Temp and humidity sensor loop with if statement

// if received command is to read temp and humidity
if (incomingData.indexOf("TH") >= 0)
{
// Wait a few seconds between measurements.
delay(2000);

// Reading temperature or humidity takes about 250 milliseconds!
// Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
h = dht.readHumidity();
// Read temperature as Celsius (the default)
t = dht.readTemperature();

// Check if any reads failed and exit early (to try again).
if (isnan(h) || isnan(t)) {
Serial.println(F("Failed to read from DHT sensor!"));
return;
}

message = "Humidity = " + String(h) + " %, Temperature = " + String(t) + " C";
// Send a sms stating the temperature and humidity measurement
send_message(message);
}
}

void receive_message()
{
if (SIM900.available() > 0)
{
incomingData = SIM900.readString(); // Get the data from the serial port.
Serial.print(incomingData);
delay(10);
}
}

void send_message(String message)
{
SIM900.println("AT+CMGF=1"); //Set the GSM Module in Text Mode
delay(100);
SIM900.println("AT+CMGS=\"+44XXXXXXXX\""); // Replace with mobile number in international format of sender (NOT the GSM module number!)
delay(100);
SIM900.println(message); // The SMS text you want to send
delay(100);
SIM900.println((char)26); // ASCII code of CTRL+Z
delay(100);
SIM900.println();
delay(1000);
}
 
Last edited:
Long separation from the boat calls for desperate measures in finding new time-consuming but cheap projects. So Arduino-nerds, what have you got?

Nice!!

couple thoughts, the arduino internal adc to measure voltage isn't the greatest, for a few quid the ads1115 4 channel is crazy accurate, plus does differential measurements so you can avoid ground loops.
How to use the ADS1115

And BME280 is a great pressure/temp/humidity sensor. Crazy accurate as well, watch the pressure drop if you lift the sensor a few feet over your head. And ds18b20 thermometers are great as well, daisy chain them so just 3 wires to the arduino.
Add a raspberry pi zero for about 0.1A and you can log all the data as well, plus do soooo much more :)

Next on the back burner I'm looking at a little board with an ESP32 presoldered on and header socket for a Pi Zero running signalk, voltage senors, temperature, 2 x nmea in/out, thermometer headers, RPM, analoge voltage output for control mostly surface mounted, jlcpcb make the boards really cheap. Then rj45 sockets and little breakout boards so you don't need to feed dozens of cable back to the board. So should be a really tidy extremely powerful boat data centre for little money and next to no power consumption.
Though I went over to micropython, soooo much nicer for a "not really a programmer" like me :)
V1, up and running - boatybits/boatymonpy
PCB_actual.jpg
 
That's an impressive layout and thanks for the code. I'm playing with Arduino too but have much less electronic or programming experience. My project is to get an Arduino Nano to read ambient pressure data from a BME280 sensor and send it via Blue tooth low energy to an app on a mobile phone. But I am a slow learner.....
 
  • Like
Reactions: GHA
GHA - as far as I'm concerned, at least, you are the undisputed king of low power DIY electronic gizmos for boats. I just hope lockdown lasts long enough to explore those suggestions.
 
Long separation from the boat calls for desperate measures in finding new time-consuming but cheap projects. So Arduino-nerds, what have you got?

Here's the first of mine - two voltage sensors, four relays and a temperature and humidity sensor to communicate by text with the boat from 100 miles away. Total cost under £40 plus £6 per month for a SIM card.

This page introduces the use of the SIM900. In-Depth: Send Receive SMS & Call with SIM900 GSM Shield & Arduino

7LvsB84l.png



Screenshot from my mobile phone
S2t8pS2l.jpg



Code
#include <SoftwareSerial.h> // Library for using serial communication
SoftwareSerial SIM900(7, 8); // Pins 7, 8 are used as used as software serial pins

// Temp and humidity parameters
#include "DHT.h"
#define DHTPIN 2 // Digital pin connected to the DHT sensor
#define DHTTYPE DHT22 // DHT 22
DHT dht(DHTPIN, DHTTYPE);
float h;
float t;

// GSM parameters
String incomingData; // for storing incoming serial data
String message = ""; // A string for storing the message
int relay_pin1 = 3; // Initialized a pin for relay module
int relay_pin2 = 4; // Initialized a pin for relay module
int relay_pin3 = 5; // Initialized a pin for relay module
int relay_pin4 = 6; // Initialized a pin for relay module

// Voltmeter code parameters
int analogInput1 = A1;
int analogInput2 = A0;
float vout1 = 0.0;
float vout2 = 0.0;
float vin1 = 0.0;
float vin2 = 0.0;
float R1 = 30000.0; //
float R2 = 7500.0; //
int value = 0;
String Voltstring = "";

void setup()
{
SIM900.begin(9600);
Serial.println("Power on");
Serial.begin(9600);
SIM900power();
delay(20000); // give time to log on to network.

// GSM setup

dht.begin();

// Temp and humidity sensor setup (using GSM baudrate of 115200)


// GSM setup 2

pinMode(relay_pin1, OUTPUT); // Setting relay pin as output pin
digitalWrite(relay_pin1, LOW); // Making relay pin initailly low
pinMode(relay_pin2, OUTPUT); // Setting relay pin as output pin
digitalWrite(relay_pin2, LOW); // Making relay pin initailly low
pinMode(relay_pin3, OUTPUT); // Setting relay pin as output pin
digitalWrite(relay_pin3, LOW); // Making relay pin initailly low
pinMode(relay_pin4, OUTPUT); // Setting relay pin as output pin
digitalWrite(relay_pin4, LOW); // Making relay pin initailly low

// set SMS mode to text mode
SIM900.print("AT+CMGF=1\r");
delay(100);

// set gsm module to tp show the output on serial out
SIM900.print("AT+CNMI=2,2,0,0,0\r");
delay(100);

// Voltmeter code setup

pinMode(analogInput1, INPUT);
pinMode(analogInput2, INPUT);
Serial.begin(9600);
Serial.print("DC VOLTMETER");

}

//Insert soft start code here
void SIM900power()
{
pinMode(9, OUTPUT);
digitalWrite(9, LOW);
delay(1000);
digitalWrite(9, HIGH);
delay(2000);
digitalWrite(9, LOW);
delay(3000);
}
// End of soft start code

void loop()
{
//Function for receiving sms
receive_message();

// Read temperature as Celsius (the default)
t = dht.readTemperature();

// if received command is to turn off relay
if (incomingData.indexOf("Hoff") >= 0)
{
digitalWrite(relay_pin1, LOW);
message = "House is turned OFF";
// Send a sms back to confirm that the relay is turned off
send_message(message);
}

// if received command is to turn on relay
if (incomingData.indexOf("Hon") >= 0)
{
digitalWrite(relay_pin1, HIGH);
message = "House is turned ON";
// Send a sms back to confirm that the relay is turned on
send_message(message);
}

// if received command is to turn off relay
if (incomingData.indexOf("Soff") >= 0)
{
digitalWrite(relay_pin2, LOW);
message = "Start is turned OFF";
// Send a sms back to confirm that the relay is turned off
send_message(message);
}

// if received command is to turn on relay
if (incomingData.indexOf("Son") >= 0)
{
digitalWrite(relay_pin2, HIGH);
message = "Start is turned ON";
// Send a sms back to confirm that the relay is turned off
send_message(message);
}

// if received command is to turn off relay
if (incomingData.indexOf("3off") >= 0)
{
digitalWrite(relay_pin3, LOW);
message = "3 is turned OFF";
// Send a sms back to confirm that the relay is turned off
send_message(message);
}

// if received command is to turn on relay
if (incomingData.indexOf("3on") >= 0)
{
digitalWrite(relay_pin3, HIGH);
message = "3 is turned ON";
// Send a sms back to confirm that the relay is turned on
send_message(message);
}

// if received command is to turn off relay
if (incomingData.indexOf("4off") >= 0)
{
digitalWrite(relay_pin4, LOW);
message = "4 is turned OFF";
// Send a sms back to confirm that the relay is turned off
send_message(message);
}

// if received command is to turn on relay
if (incomingData.indexOf("4on") >= 0)
{
digitalWrite(relay_pin4, HIGH);
message = "4 is turned ON";
// Send a sms back to confirm that the relay is turned off
send_message(message);
}
// if received command is to read Voltage1
if (incomingData.indexOf("HV") >= 0)
{

// read the value at analog input
value = analogRead(analogInput1);
vout1 = (value * 5.0) / 1024.0; // see text
vin1 = (vout1 * 0.828) / (R2 / (R1 + R2));
Voltstring = String(vin1);
message = "House = " + Voltstring + "V";
// Send a sms stating the voltage measurement
send_message(message);

}
// if received command is to read Voltage2
if (incomingData.indexOf("SV") >= 0)
{

// read the value at analog input
value = analogRead(analogInput2);
vout2 = (value * 5.0) / 1024.0; // see text
vin2 = (vout2 * 0.828) / (R2 / (R1 + R2));
Voltstring = String(vin2);
message = "Start = " + Voltstring + "V";
// Send a sms stating the voltage measurement
send_message(message);
}

// Temp and humidity sensor loop with if statement

// if received command is to read temp and humidity
if (incomingData.indexOf("TH") >= 0)
{
// Wait a few seconds between measurements.
delay(2000);

// Reading temperature or humidity takes about 250 milliseconds!
// Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
h = dht.readHumidity();
// Read temperature as Celsius (the default)
t = dht.readTemperature();

// Check if any reads failed and exit early (to try again).
if (isnan(h) || isnan(t)) {
Serial.println(F("Failed to read from DHT sensor!"));
return;
}

message = "Humidity = " + String(h) + " %, Temperature = " + String(t) + " C";
// Send a sms stating the temperature and humidity measurement
send_message(message);
}
}

void receive_message()
{
if (SIM900.available() > 0)
{
incomingData = SIM900.readString(); // Get the data from the serial port.
Serial.print(incomingData);
delay(10);
}
}

void send_message(String message)
{
SIM900.println("AT+CMGF=1"); //Set the GSM Module in Text Mode
delay(100);
SIM900.println("AT+CMGS=\"+44XXXXXXXX\""); // Replace with mobile number in international format of sender (NOT the GSM module number!)
delay(100);
SIM900.println(message); // The SMS text you want to send
delay(100);
SIM900.println((char)26); // ASCII code of CTRL+Z
delay(100);
SIM900.println();
delay(1000);
}

Great project. I'd like to do something similar. You could get your monthly costs down by using 1p mobile (EE network, 4G).

UKs cheapest PAYG mobile tariff

A £10 top up lasts 120 days - roughly £2.50 per month. Not a massive saving but it'll buy you a beer.
 
Great project. I'd like to do something similar. You could get your monthly costs down by using 1p mobile (EE network, 4G).

UKs cheapest PAYG mobile tariff

A £10 top up lasts 120 days - roughly £2.50 per month. Not a massive saving but it'll buy you a beer.

Thanks for the suggestions. You have to be careful to ensure that the SIM does 2G. I tried SMARTY but it only does 3G upwards. The other factor is that some people have made errors in coding resulting in thousands of texts being sent by the SIM. So people tend to recommend an unlimited texts deal which is what I have with Giffgaff's lowest tariff.
 
Thanks for the suggestions. You have to be careful to ensure that the SIM does 2G. I tried SMARTY but it only does 3G upwards. The other factor is that some people have made errors in coding resulting in thousands of texts being sent by the SIM. So people tend to recommend an unlimited texts deal which is what I have with Giffgaff's lowest tariff.
Agree with the unlimited SMS's, been there done that
 
couple thoughts, the arduino internal adc to measure voltage isn't the greatest, for a few quid the ads1115 4 channel is crazy accurate, plus does differential measurements so you can avoid ground loops.
How to use the ADS1115

I'm sold on the ADS1115 as I could do with some voltage accuracy for my lithium pack. And I'm glad to say I've managed to scrape up the £4.23 to pay for it.

P.S. I'm still adjusting to these crazily low prices for electronic bits. I've twice ordered a low cost item for a fiver only to find that I've actually ordered x 5.
 
Last edited:
I'm sold on the ADS1115 as I could do with some voltage accuracy for my lithium pack. And I'm glad to say I've managed to scrape up the £4.23 to pay for it.

P.S. I'm still adjusting to these crazily low prices for electronic bits. I've twice ordered a low cost item for a fiver only to find that I've actually ordered x 5.
Yep, way to go. JLCPCB is way to go as well imho, get a tidy little board back with all the components including resisters to drop the voltage down presoldered on and holes for you to solder on the terminals. Such a cool service :cool: Think they even do some through hole soldering now cheap, so you get a complete board back.
 
Thanks for the suggestions. You have to be careful to ensure that the SIM does 2G. I tried SMARTY but it only does 3G upwards. The other factor is that some people have made errors in coding resulting in thousands of texts being sent by the SIM. So people tend to recommend an unlimited texts deal which is what I have with Giffgaff's lowest tariff.

good points. Just checked 1p mobile and it does 2G which is good news. They also seem to pitch themselves at the IOT market.
UKs cheapest PAYG mobile tariff

I also spotted this:
ARDUINO SIM - MKR GSM 1400 Cellular Kit
which I hadn't seen before. Its more expensive but opens up the possibility of web apps to view data rather than SMS only. All interesting stuff!
 
These projects fascinate me to the extent that I've built a couple of devices to get data onto my N2k bus using the reverse engineered designs from Timo Lappalainen. The first was an engine room temperature sender and the second was engine data. Both were succesful.

My holy grail is to grab depth from my standalone Seatalk sounder and put it onto the N2k bus. My hurdle is two-fold though. Firstly the fact that seatalk is 9-bit and secondly that I really struggle to find the time to research, learn and ultimately remember all the finer details of Arduino programming. AngusMcDoon, is there any way you could isolate the Sealtalk reading code from your project such that I could insert it into my N2k code please? I've looked at your Github but I'm not quite sure which bit I need.
 
These projects fascinate me to the extent ...................

I seem to recall that Angus doesn't use the Arduino OS; I think he uses C.

You're welcome to my SeaTalk parser which is also written in C if you'd like it.
Regarding 9-bits, you just need to set the UART to 9-bits. The UARTs used on the Arduino AVRs are capable of 5, 6, 7, 8 or 9-bit operation. But I've no idea if the Arduino OS supports anything other than 8-bit operation.
 
These projects fascinate me to the extent that I've built a couple of devices to get data onto my N2k bus using the reverse engineered designs from Timo Lappalainen. The first was an engine room temperature sender and the second was engine data. Both were succesful.

My holy grail is to grab depth from my standalone Seatalk sounder and put it onto the N2k bus. My hurdle is two-fold though. Firstly the fact that seatalk is 9-bit and secondly that I really struggle to find the time to research, learn and ultimately remember all the finer details of Arduino programming. AngusMcDoon, is there any way you could isolate the Sealtalk reading code from your project such that I could insert it into my N2k code please? I've looked at your Github but I'm not quite sure which bit I need.
One way to do that and so much more is to use a raspberry pi zero, next to no power and signalk reads seatalk 1 out of the box, but you would need something to get the voltages down to 3.3v. And a usb/can adaptor. SignalK/signalk-server
That would get seatalk to the n2k network and give you access to the hundred and one other things signalk can do :cool:
 
... and with a 20euro CANBUS/RS485 HAT on the raspberry, you can get from seatalk your data on N2K :p
well, I'm doing the opposite thing - reading N2K bus and sending the data to an influxDB to be formated and read using grafana.

and to be on topic, done a lot of work but specifically reading engine data and pumping them to the N2K bus as well as touch screens to view (and alter) some non standard N2K PGNs
all good fun... If the lockdown lasts another winter, I'll have more custom teensy boxes pumping N2K messages than actual Garmin N2K devices :cool: Currently 6 custom boxes and another 2 in the making!

V.
 
Top