hi I have two pieces of code that work perfectly but when we merge them they dont work, can someone help find the fault. one code takes the output from a geophone through an amp and ADS1115 and presents the highest value in each second. The other takes the output from that and puts it in a MOBbus holding register server. both work separately but when merged the client times out. I am using a Nano.
Merged code
#include "ADS1X15.h" //merged by george
#include <CircularBuffer.hpp>
#include <ModbusRTUSlave.h> // ModbusRTUSlave by CM Bullinar
// Initialise variables for reading from the ADC
ADS1115 ADS(0x48);//mb
int i;
CircularBuffer<int16_t, 10> readingsBuffer;// number of readings in the buffer
int16_t highestReading;
// Initialise modbus library and variables
ModbusRTUSlave modbus_slave(Serial);
const uint8_t slaveID = 1;
const uint32_t baud = 9600;
uint16_t holdingRegisters[20] = {0};
void setup() {// ADS111x setup
Serial.begin(9600);
Serial.println(__FILE__);
Serial.print("ADS1X15_LIB_VERSION: ");
Serial.println(ADS1X15_LIB_VERSION);
ADS.begin();
modbus_slave.configureHoldingRegisters(holdingRegisters, 21);
modbus_slave.configureHoldingRegisters(holdingRegisters, 22);
modbus_slave.begin(slaveID, baud, SERIAL_8N1);
i = 0;
}
void loop() {
ADS.setGain(0);
// if the value is higher or lower than the one 10 before it
// print the current value
// or if there is more than one occurrence
// take the higher value
static const unsigned long REFRESH_INTERVAL = 1000; // ms refresh highest reading interval
static unsigned long lastRefreshTime = 0;
// Read from the senser and push it onto the circular buffer
int16_t currentReading = ADS.readADC(0);
readingsBuffer.push(currentReading);
// If the reading is higher or lower than the one at the end of the buffer (10 before) and it is higher than the current highest reading
if (abs(readingsBuffer.first()) > readingsBuffer.last() && currentReading > highestReading || !highestReading) {
// Set the highest reading to be the current one
highestReading = currentReading;
}
// Every second, print the current highest reading and then set it to 0;
if(millis() - lastRefreshTime >= REFRESH_INTERVAL)
{
lastRefreshTime += REFRESH_INTERVAL;
//Serial.println(highestReading);
holdingRegisters[0] = 12345; //highestReading; //changed from =sensor
modbus_slave.poll();
highestReading = 0;
}
}
Modbus
#include <ModbusRTUSlave.h> // ModbusRTUSlave by CM Bullinar
ModbusRTUSlave modbus_slave(Serial);
const uint8_t slaveID = 1;
const uint32_t baud = 9600;
uint16_t holdingRegisters[20] = {0};
int sensor;
void setup() {
// put your setup code here, to run once:
modbus_slave.configureHoldingRegisters(holdingRegisters, 21);
modbus_slave.configureHoldingRegisters(holdingRegisters, 22);
modbus_slave.begin(slaveID, baud, SERIAL_8N1);
}
void loop() {
// put your main code here, to run repeatedly:
sensor = analogRead(A0);
holdingRegisters[0] = sensor;
modbus_slave.poll();
}
Read ADC
#include "ADS1X15.h"
#include <CircularBuffer.hpp>
ADS1115 ADS(0x48);
int i;
CircularBuffer<int16_t, 10> readingsBuffer;// number of readings in the buffer
int16_t highestReading;
void setup() {// ADS111x setup
Serial.begin(9600);
Serial.println(__FILE__);
Serial.print("ADS1X15_LIB_VERSION: ");
Serial.println(ADS1X15_LIB_VERSION);
ADS.begin();
i = 0;
}
void loop() {
ADS.setGain(0);
// if the value is higher or lower than the one 10 before it
// print the current value
// if there is more than one occurrence within 128 readings
// take the highest occurrence and print
static const unsigned long REFRESH_INTERVAL = 1000; // ms refresh highest reading interval
static unsigned long lastRefreshTime = 0;
// Read from the senser and push it onto the circular buffer
int16_t currentReading = ADS.readADC(0);
readingsBuffer.push(currentReading);
// If the reading is higher or lower than the one at the end of the buffer (10 before) and it is higher than the current highest reading
if (abs(readingsBuffer.first()) > readingsBuffer.last() && currentReading > highestReading || !highestReading) {
// Set the highest reading to be the current one
highestReading = currentReading;
}
// Every second, print the current highest reading and then set it to 0;
if(millis() - lastRefreshTime >= REFRESH_INTERVAL)
{
lastRefreshTime += REFRESH_INTERVAL;
Serial.println(highestReading);
highestReading = 0;
}
}
I moved your topic to an appropriate forum category @ed1arris.
In the future, please take some time to pick the forum category that best suits the subject of your topic. There is an "About the _____ category" topic at the top of each category that explains its purpose.
Please post the merged code.
"Don't work" tells nothing.
Using temporary serial.print at strategic points in the code is recommended, and watching serial monitor.
@ed1arris You say there's a timeout. Maybe I missed it, but where's that in the code? What, exactly, is the message you're getting, please? Cut and paste or export it from the IDE, put it in a new message, in quotes.
No more editing your original message, okay? Just post new info in a new message. It's confusing as HExx, and helpers will get grumpy if it continues.
@Railroader Sorry about the editing the first post, last bit of code, would not accept the code tags. The time out is in the client program which is labview. But as I say the modbus code works fine before merging. The server didnt get a reply from Arduino quick enough which is usually caused by something stupid like wrong address.
This is the error message from labview "VISA: (Hex 0xBFFF0015) Timeout expired before operation completed"
I just noticed that when I reposted the merged code I used an edit. That is I had changed (3rd line from the bottom) from "holdingRegisters[0] = last reading;" to holdingRegisters[0] = 12345; And that doesnt work either so it is not that "modbus" isnt getting data from "ReadADC". so I am thinking perhaps "readADC" is screwing up the modbus somehow?
You need to go through the merged code line by line, and make sure that each line has a specific, required task, which should be carried out at that particular place in the code.
For example, this line should be in setup(), and performs no useful function that must be carried out as the first line of loop()
I suspect this code, in your merged setup, is wildly confusing the Modbus interface. I don't think you can talk Modbus over Serial at the same time as you print debugging information like this over Serial. Try just commenting this out, see if that helps.
@camsysca Genius! that sorted it, I left serial.begin (9600) in though.
Just have a slight problem now that the client still times out if I put it off highlight execution (that makes it run slowly). Are there any issues with Arduino running slowly?
This is the final code that works (in case anyone wants to refer), only issue is the speed the client reads it. if client is on slow mode, it works. If client is normal it times out.
#include "ADS1X15.h" //merged by george
#include <CircularBuffer.hpp>
#include <ModbusRTUSlave.h> // ModbusRTUSlave by CM Bullinar
// Initialise variables for reading from the ADC
ADS1115 ADS(0x48);//mb
//int i=0;
CircularBuffer<int16_t, 10> readingsBuffer;// number of readings in the buffer
int16_t highestReading;
// Initialise modbus library and variables
ModbusRTUSlave modbus_slave(Serial);
const uint8_t slaveID = 2;
const uint32_t baud = 4800;
uint16_t holdingRegisters[20] = {0};
void setup() {// ADS111x setup
Serial.begin(9600);
//Serial.println(__FILE__);
//Serial.print("ADS1X15_LIB_VERSION: ");
//Serial.println(ADS1X15_LIB_VERSION);
ADS.begin();
ADS.setGain(0);
modbus_slave.configureHoldingRegisters(holdingRegisters, 20);
modbus_slave.begin(slaveID, baud, SERIAL_8N1);
}
void loop() {
// if the value is higher or lower than the one 10 before it print the current value
// or if there is more than one occurrence take the higher value
static const unsigned long REFRESH_INTERVAL = 1000; // ms refresh highest reading interval
static unsigned long lastRefreshTime = 0;
// Read from the senser and push it onto the circular buffer
int16_t currentReading = ADS.readADC(0);
readingsBuffer.push(currentReading);
// If the reading is higher or lower than the one at the end of the buffer (10 before) and it is higher than the current highest reading
if (abs(readingsBuffer.first()) > readingsBuffer.last() && currentReading > highestReading || !highestReading) {
// Set the highest reading to be the current one
highestReading = currentReading;
}
// Every second, print the current highest reading and then set it to 0;
if(millis() - lastRefreshTime >= REFRESH_INTERVAL)
lastRefreshTime += REFRESH_INTERVAL;
{
//Serial.println(highestReading);
holdingRegisters[2] = highestReading; //changed from =sensor
modbus_slave.poll();
highestReading = 0;
}
}