Arduino Mega and RS485 Modbus Sensor - arduino

I'm trying to connect a soil sensor using RS485 communication to arduino mega and I can't get it to work. I'm using the SparkFun RS485 breakout: https://www.sparkfun.com/products/10124
I've connected TX to pin 18, RS to pin 19 and RTS to pin 8.
I've tried to adapt the code from here: https://www.youtube.com/watch?v=tBw15SfmuwI using the sensor's manufacturers default setting:
Modbus address fixed to 0
The communication configuration is 9600,N,8,1(9600bps, no check bit, 8 data bits,
1 stop bit)
Communication protocol is Modbus-RTU
While the addresses I need to read are 0x0000-0x0002.
However, I get random characters as output when I open the serial monitor "?", any idea why? I'd appreciate any help reading the sensor's output.
This is the code I've used:
#include <ModbusMaster.h>
#define MAX485_DE 8
#define MAX485_RE_NEG 8
ModbusMaster node;
void preTransmission () {
digitalWrite(MAX485_RE_NEG, 1);
digitalWrite(MAX485_DE, 1);
}
void postTransmission () {
digitalWrite(MAX485_RE_NEG, 0);
digitalWrite(MAX485_DE, 0);
}
void setup() {
pinMode(MAX485_RE_NEG, OUTPUT);
pinMode(MAX485_DE, OUTPUT);
digitalWrite(MAX485_RE_NEG, 0);
digitalWrite(MAX485_DE, 0);
Serial.begin(9600);
node.begin(0,Serial);
node.preTransmission(preTransmission);
node.postTransmission(postTransmission);
}
void loop() {
uint8_t resultMain;
resultMain = node.readInputRegisters(0x0000, 3);
if (resultMain == node.ku8MBSuccess) {
Serial.println("-------");
Serial.print("Temp: ");
Serial.println(node.getResponseBuffer(0x00) /100);
Serial.print("VWC: ");
Serial.println(node.getResponseBuffer(0x01) /100);
Serial.print("EC: ");
Serial.println(node.getResponseBuffer(0x02) /100);
}
}

The arduino mega has 3 serial ports:
Serial
Serial1
Serial2
You could think of it as Serial as Serial0 (the zero is never written). This port is hardwired to the USB port on the arduino mega.
Your RS485 breakout board is connected to Serial1. You may notice the screenprinting on the mega next to pins 18 and 19 says TX1 and RX1.
So when you initialize your node at this line:
node.begin(0,Serial);
you should pass it Serial1 instead of Serial
eg
node.begin(0,Serial1);

Related

Arduino PLC Modbus Communication to read plc input register

I am trying to communicate Arduino UNO and Wecon(LX3v-0806MR) PLC with RS485. Here the arduino is the master and the plc is the slave. I want to now read the values from the input registers (04) of plc and present it on serial monitor. For that purpose I am using the following code.
#include <ModbusMaster.h>
/*!
We're using a MAX485-compatible RS485 Transceiver.
Rx/Tx is hooked up to the hardware serial port at 'Serial'.
The Data Enable and Receiver Enable pins are hooked up as follows:
*/
#define MAX485_DE 3
#define MAX485_RE_NEG 2
// instantiate ModbusMaster object
ModbusMaster node;
void preTransmission()
{
digitalWrite(MAX485_RE_NEG, 1);
digitalWrite(MAX485_DE, 1);
}
void postTransmission()
{
digitalWrite(MAX485_RE_NEG, 0);
digitalWrite(MAX485_DE, 0);
}
void setup()
{
pinMode(MAX485_RE_NEG, OUTPUT);
pinMode(MAX485_DE, OUTPUT);
// Init in receive mode
digitalWrite(MAX485_RE_NEG, 0);
digitalWrite(MAX485_DE, 0);
// Modbus communication runs at 115200 baud
Serial.begin(115200);
// Modbus slave ID 1
node.begin(1, Serial);
// Callbacks allow us to configure the RS485 transceiver correctly
node.preTransmission(preTransmission);
node.postTransmission(postTransmission);
}
bool state = true;
void loop()
{
uint8_t result;
uint16_t data[6];
// Toggle the coil at address 0x0002 (Manual Load Control)
result = node.writeSingleCoil(0x0002, state);
state = !state;
// Read 16 registers starting at 0x3100)
result = node.readInputRegisters(0x3100, 16);
if (result == node.ku8MBSuccess)
{
Serial.print("Vbatt: ");
Serial.println(node.getResponseBuffer(0x04)/100.0f);
Serial.print("Vload: ");
Serial.println(node.getResponseBuffer(0xC0)/100.0f);
Serial.print("Pload: ");
Serial.println((node.getResponseBuffer(0x0D) +
node.getResponseBuffer(0x0E) << 16)/100.0f);
}
delay(1000);
}
I tried the codes many a times but it is not working. If anyone knows how to do it please share the codes with me. I just want read int value from plc.
*Note: The sensor used is for TTL to rs485 is MAX485.

Arduino mega SIM800l special characters

I have a problem with the Arduino mega board and the SIM800L module I connect to the RX and TX pins of the module and when I enter the serial monitor it returns these characters, what could it be?
void setup() {
Serial.begin(9600);
//Begin serial communication with Arduino and SIM800L
Serial1.begin(9600);
}
void loop() {
delay(500);
while (Serial.available()) {
Serial1.write(Serial.read()); //Forward what Serial received to Software Serial Port
}
while(Serial1.available()) {
Serial.write(Serial1.read()); //Forward what Software Serial received to Serial Port
}
}
After so much searching and looking on the oscilloscope I have found the solution, In case you are using a LM2596 buck converter to power up the module, remember to common all the ground of the circuit.

How does my ESP8266/NodeMCU communicate with my GSM Module SIM800L?

so I want to connect my SIM800L GSM Module to my NodeMCU. I bought a LM2596 DC-DC voltage regulator to convert the output voltage to ~4V for the SIM800L. Input voltage for the regulator is 9V/1A.
Everything is connected: RX from GSM to D5 (GPIO14), TX to D6 (GPIO12) and RST to D7 (GPIO13). The GPIOs are deliberately chosen, since I've read online, that the RX/TX Pins on the NodeMCU are used internally. I tried matching RX/TX pins before, but it's the same result (that's why I am certain, it has to be my code that is defect). A SIM card is also inserted in the GSM Module (with PIN).
I'm coding on the Arduino IDE and I'm using the GSMSim and SoftwareSerial libraries for connecting to the GSM Module. I've tried the example sketches from the GSMSim to communicate to the GSM Module, but I'm not getting any answer on my serial monitor.
I also tried manually sending commands to the GSM Module.
#include <GSMSim.h>
#include <SoftwareSerial.h>
// You can use any Serial interface. I recommended HardwareSerial. Please use the library with highiest baudrate.
// In examples, i used HardwareSerial. You can change it anymore.
#define RX 14
#define TX 12
#define RESET 13
SoftwareSerial serial(RX, TX);
GSMSim gsmModule(serial, RESET);
void setup() {
serial.begin(115200); // If you dont change module baudrate, it comes with auto baudrate.
while(!serial) ;
Serial.begin(115200); // Serial for debug...
while(!Serial) ;
Serial.println("");
Serial.println("serial begin");
// Init module...
gsmModule.init(); // use for reseting module. Use it if you dont have any valid reason.
delay(100);
gsmModule.sendATCommand("AT+GMR");
if(serial.available()) Serial.println(serial.readString());
Serial.println("Sent AT");
}
OUTPUT:
serial.begin
Sent AT
Another example with the modified GSMSim_HTTP sketch:
#include <GSMSim.h>
#include <SoftwareSerial.h>
// You can use any Serial interface. I recommended HardwareSerial. Please use the library with highiest baudrate.
// In examples, i used HardwareSerial. You can change it anymore.
#define RX 14
#define TX 12
#define RESET 13
SoftwareSerial serial(RX, TX);
GSMSim http(serial, RESET);
static volatile int num = 0;
void setup() {
serial.begin(115200); // If you dont change module baudrate, it comes with auto baudrate.
while(!serial) {
; // wait for module for connect.
}
Serial.begin(115200); // Serial for debug...
// Init module...
http.init(); // use for init module. Use it if you dont have any valid reason.
Serial.print("Set Phone Function... ");
Serial.println(http.setPhoneFunc(1));
//delay(1000);
Serial.print("is Module Registered to Network?... ");
Serial.println(http.isRegistered());
//delay(1000);
Serial.print("Signal Quality... ");
Serial.println(http.signalQuality());
//delay(1000);
Serial.print("Operator Name... ");
Serial.println(http.operatorNameFromSim());
//delay(1000);
//Serial.print("GPRS Init... ");
//Serial.println(http.gprsInit("internet")); // Its optional. You can set apn, user and password with this method. Default APN: "internet" Default USER: "" Default PWD: ""
//delay(1000);
Serial.print("Connect GPRS... ");
Serial.println(http.connect());
//delay(1000);
Serial.print("Get IP Address... ");
Serial.println(http.getIP());
delay(1000);
Serial.print("Get... ");
Serial.println(http.get("sera.erdemarslan.com/test.php"));
delay(1000);
Serial.print("Get with SSL and read returned data... ");
Serial.println(http.getWithSSL("erdemarslan.com/test.php", true));
delay(1000);
Serial.print("Post... ");
Serial.println(http.post("sera.erdemarslan.com/test.php", "name=Erdem&surname=Arslan", "application/x-www-form-urlencoded"));
delay(1000);
Serial.print("Post with SSL and read returned data... ");
Serial.println(http.post("erdemarslan.com/test.php", "name=Erdem&surname=Arslan", "application/x-www-form-urlencoded", true));
delay(1000);
Serial.print("Close GPRS... ");
Serial.println(http.closeConn());
//delay(1000);
// For other methods please look at readme.txt file.
}
void loop() {
// Use your Serial interface...
if(serial.available()) {
String buffer = "";
buffer = Serial1.readString();
num = num + 1;
Serial.print(num);
Serial.print(". ");
Serial.println(buffer);
}
// put your main code here, to run repeatedly:
}
OUTPUT:
serial.begin
Set Phone Function... 0
is Module Registered to Network?... 0
Signal Quality... 99
Operator Name... NOT CONNECTED
Connect GPRS... 0
Get IP Address...
Get module date time... ERROR:NOT_GET_DATETIME
Set timezone and time server... 0
Sync date time from server... AT_COMMAND_ERROR
Get module date time after sycn... ERROR:NOT_GET_DATETIME
Close GPRS... 0
I hope it's something obvious, since I am not familiar with AT commands at all.
Thanks!

Communication between Arduino Nano and HM-10 BLE controller is not working

I want to check if communication is working between my SerialMonitor in Arduino IDE and BLE controller.
I typed command AT to my SerialMonitor and it suppose to return OK response but nothing happened.
This is scheme what I used:
Code:
#include <SoftwareSerial.h>
SoftwareSerial bleSerial(2, 3); // RX, TX
void setup() {
//initialize serial port for logs
Serial.begin(9600);
while (!Serial) {
}
bleSerial.begin(9600);
}
void loop() {
if (bleSerial.available()) {
Serial.write(bleSerial.read());
}
if (Serial.available()) {
bleSerial.write(Serial.read());
}
}
UPDATE:
Changed values for SoftwareSerial bleSerial(3, 2); // RX, TX still doesnt work.
UPDATE2:
I've tried switching pins and code, nothing works. I should at least see HM-10 controller in my bluetooth devices on my Android phone, but I cant see anything.
UPDATE3:
I've used code from this Stackoverflow post and its working fine. I can finally see controller in my bluetooth devices on my Android phone also It returned name MLT-BT05 after AT+NAME? command. Looks like you have to read message per char and put delay 10ms between chars, otherwise it will not be possible to read message from BLE controller. That was the only problem.
You should connect RX-TX and TX-RX (not RX-RX and TX-TX like your graphic shows) so change the cables and the code from
SoftwareSerial bleSerial(2, 3); // RX, TX
to
SoftwareSerial bleSerial(3, 2); // RX, TX
Connect according to this graphic (incl voltage divider)
Abd use the following sketch to test (read comments for details):
// SerialIn_SerialOut_HM-10_01
//
// Uses hardware serial to talk to the host computer and AltSoftSerial for communication with the bluetooth module
//
// What ever is entered in the serial monitor is sent to the connected device
// Anything received from the connected device is copied to the serial monitor
// Does not send line endings to the HM-10
//
// Pins
// BT VCC to Arduino 5V out.
// BT GND to GND
// Arduino D8 (SS RX) - BT TX no need voltage divider
// Arduino D9 (SS TX) - BT RX through a voltage divider (5v to 3.3v)
//
#include <SoftwareSerial.h>
SoftwareSerial BTserial;
char c=' ';
bool NL = true;
void setup()
{
Serial.begin(9600);
Serial.print("Sketch: "); Serial.println(__FILE__);
Serial.print("Uploaded: "); Serial.println(__DATE__);
Serial.println(" ");
BTserial.begin(9600);
Serial.println("BTserial started at 9600");
}
void loop()
{
// Read from the Bluetooth module and send to the Arduino Serial Monitor
if (BTserial.available())
{
c = BTserial.read();
Serial.write(c);
}
// Read from the Serial Monitor and send to the Bluetooth module
if (Serial.available())
{
c = Serial.read();
if (c!=10 & c!=13 )
{
BTserial.write(c);
}
// Echo the user input to the main window. The ">" character indicates the user entered text.
if (NL) { Serial.print("\r\n>"); NL = false; }
Serial.write(c);
if (c==10) { NL = true; }
}
}

Connect nodemcu with 1602 lcd without I2C

I want to connect Nodemcu esp8266 and I2C 1602. I just want to show some text from esp8266 at I2C without any other sensor/hardware in between. What should be the pins' connection between the Nodemcu and I2C?
I would be very thankful if somebody please tell me the comparison of Nodemcu and Arduino pins?
Actually, there are a couple of examples to do this, but there is a library for I2C connection of common 16x2 LCD converters like this:
Just grab the library and put it in your libraries directory and use one of the examples:
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 20, 4); // set the LCD address to 0x27 for a 16 chars and 2 line display
void setup()
{
lcd.init(); // initialize the lcd
// Print a message to the LCD.
lcd.backlight();
lcd.setCursor(3, 0);
lcd.print("Hello, world!");
lcd.setCursor(2, 1);
lcd.print("Ywrobot Arduino!");
lcd.setCursor(0, 2);
lcd.print("Arduino LCM IIC 2004");
lcd.setCursor(2, 3);
lcd.print("Power By Ec-yuan!");
}
void loop()
{
}

Resources