Hello, and thank you for reading this and any help is greatly appreciated.
I have been working on a project for some time now, and learning a lot. It's my first big project.
My goal is to have a multi-channel voltage meter with an LCD display. I also would like to have it speak Modbus protocol to a SCADA HMI to display voltages and trend the data.
I have the voltage meter part working great using a shield from rascalmicro.com called the The Precision Voltage Shield Here's a picture of the shield reading voltages very accurately of a 48v battery array.
At the time of the picture I was using Ethernet shield v1 from Seeedstudio. I've had some trouble with it, so I now have V2. It's got a w5200 chip, and other improvements. I found a library that's a modified version of the Arduino included w5100.h and .cpp files to allow you to use the examples with this shield. It seams to work great when using it by itself. No other shields attached.
I seem to have everything working, but not together. I can get a modbus project working great when only using the Ethernet shield. The voltage shield works great, with the LCD. It's when I try to add it all together it fails.
Here's what fails. and I'll include all the code. With it all together, I see the voltages on the LCD, and in the serial monitor. I can not get the Modbus protocol to work. I can ping the IP address of the Ethernet shield with no problem, but when I try to connect to port 502 it refuses the connection. I'm using a program called Hercules to try to establish a connection, and here's a screen shot of it.
Since I can get everything working when done individually, I'm guessing it's maybe a SPI conflict somehow? Now, again I'm new to this and still have lots to learn.
Here's the code:
Arduino Sketch
#include <SPI.h>
#include <LiquidCrystal.h>
#include <Ethernet.h>
#include <Mudbus.h>
LiquidCrystal lcd(14, 15, 16, 17, 18, 19);
Mudbus Mb;
#define SCALE_FACTOR 0.000152587890625
#define SCALE_FACTOR_1 SCALE_FACTOR * 3.681
#define SCALE_FACTOR_2 SCALE_FACTOR * 6.642
#define SCALE_FACTOR_3 SCALE_FACTOR * 11.096
#define SCALE_FACTOR_4 SCALE_FACTOR * 12.982
// 10/(2^16) = 0.000152587890625
// To find multiply factor (R2+R1)/R2
#define BUSY 3
#define RESET 2
#define START_CONVERSION 5
#define CHIP_SELECT 9
#define MISO 12
#define TOTAL_RAW_BYTES 16
int bytesToRead = TOTAL_RAW_BYTES;
byte raw[TOTAL_RAW_BYTES];
signed long parsed[8];
void setup() {
uint8_t mac[] = { 0x90, 0xA2, 0xDA, 0x00, 0x51, 0x06 };
uint8_t ip[] = { 192, 168, 1, 143 };
uint8_t gateway[] = { 192, 168, 1, 1 };
uint8_t subnet[] = { 255, 255, 255, 0 };
pinMode(BUSY, INPUT);
pinMode(RESET, OUTPUT);
pinMode(START_CONVERSION, OUTPUT);
pinMode(MISO, INPUT);
SPI.begin();
Ethernet.begin(mac, ip, gateway, subnet);
Serial.begin(115200);
lcd.begin(20, 4);
digitalWrite(START_CONVERSION, HIGH);
digitalWrite(CHIP_SELECT, HIGH);
digitalWrite(RESET, HIGH);
delay(1);
digitalWrite(RESET, LOW);
}
void loop() {
Mb.Run();
Mb.R[0] = 100;
int i;
digitalWrite(START_CONVERSION, LOW);
delayMicroseconds(10);
digitalWrite(START_CONVERSION, HIGH);
while (digitalRead(BUSY) == HIGH) {
// wait for conversion to complete
}
digitalWrite(CHIP_SELECT, LOW);
while (bytesToRead > 0) {
raw[TOTAL_RAW_BYTES - bytesToRead] = SPI.transfer(0x00);
bytesToRead--;
}
digitalWrite(CHIP_SELECT, HIGH);
bytesToRead = TOTAL_RAW_BYTES;
parseRawBytes();
for(i=0; i<8; i++) {
Serial.print((float)parsed[i] * SCALE_FACTOR, 5);
Serial.print(",");
}
Serial.print("\r\n");
delay(1000);
// Battery 1
lcd.setCursor(0, 0);
lcd.print("1:");
lcd.setCursor(3, 0);
lcd.print(parsed[0] * SCALE_FACTOR_1, 2);
lcd.setCursor(8, 0);
lcd.print(" |");
// Battery 2
lcd.setCursor(0, 1);
lcd.print("2:");
lcd.setCursor(3, 1);
lcd.print(parsed[1] * SCALE_FACTOR_2 - parsed[0] * SCALE_FACTOR_1, 2);
lcd.setCursor(8, 1);
lcd.print(" |");
// Battery 3
lcd.setCursor(0, 2);
lcd.print("3:");
lcd.setCursor(3, 2);
lcd.print(parsed[2] * SCALE_FACTOR_3 - parsed[1] * SCALE_FACTOR_2, 2);
lcd.setCursor(8, 2);
lcd.print(" |");
// Battery 4
lcd.setCursor(0, 3);
lcd.print("4:");
lcd.setCursor(3, 3);
lcd.print(parsed[3] * SCALE_FACTOR_4 - parsed[2] * SCALE_FACTOR_3, 2);
lcd.setCursor(8, 3);
lcd.print(" |");
// Total Voltage
lcd.setCursor(13, 0);
lcd.print("Total");
lcd.setCursor(13, 1);
lcd.print(parsed[3] * SCALE_FACTOR_4, 2);
}
void parseRawBytes() {
int i;
parsed[0] = (raw[0] << 8) + raw[1];
parsed[1] = (raw[2] << 8) + raw[3];
parsed[2] = (raw[4] << 8) + raw[5];
parsed[3] = (raw[6] << 8) + raw[7];
parsed[4] = (raw[8] << 8) + raw[9];
parsed[5] = (raw[10] << 8) + raw[11];
parsed[6] = (raw[12] << 8) + raw[13];
parsed[7] = (raw[14] << 8) + raw[15];
for(i=0; i<8; i++) {
parsed[i] = fixSignBit(parsed[i]);
}
}
long fixSignBit(long reading) {
if(reading & 0x8000) { // if reading is < 0 (stored as two's complement)
return reading | 0xFFFF0000; // set bits 31-16
} else {
return reading;
}
}
I tried to post the modified w5100.h and .cpp files along with the Modbus files, but it would not allow me to. So, I put them in a .zip file so you can download them if you want to see them as well.
Again thank you for any help and guidance.
Files.zip (10.4 KB)