Go Down

Topic: Wireless voltmeter with Modbus - Help Please :-) (Read 656 times) previous topic - next topic

yeti195

Hello. 

This is such an awesome forum, and I have learned so much about Arduino in the short time I have been playing with it. 

I'm now against a wall again, and would really love some help, and thank you way in advance for any help offered.

I have had a battery voltage meter working pretty well now with the modbus tcp/ip protocol added so I can read the voltage of a battery on a HMI screen remotely over Ethernet.

A previous thread with the code I used is in this thread:
http://forum.arduino.cc/index.php?topic=240720.msg1726716#msg1726716

Now however, I want to take it to the next step.  The voltage readings were close, but I was wanting something a little more accurate.  I found this site.  http://rascalmicro.com/index/  And he offers under the "Store" a Precision voltage shield.  It's got 8 inputs, and works really, really great.  I'm monitoring a 48v battery array using 4 12v batteries.  I'm also displaying the voltage readings on a LCD screen.  This project is now working really great.  I'll attach a photo of the setup using 4 smaller batteries for testing. 

Now, the hard part.  I purchased a Wifly shield from Sparkfun.  I would like to add this to this project, with Modbus.  This is what I can't get working.  I have the Wifly configured and on my network.  I can ping it.  If I attach it to this project on top of the Rascal shield, the LCD quits working.  And I have no idea how to pass data through the Wifly.  It's totally different that my Ethernet shield.   I think I have SPI conflicts as well, but being really new at this I keep just getting more confused.

Here's my code without the Wifly, and Modbus.  Could anyone offer any advice on how to add the Wifly and Modbus?

Again, any help is greatly appreciated. 


Code: [Select]


#include <SPI.h>
#include <LiquidCrystal.h>

// Using Analog pins 0 - 5 as digital outputs for the LCD. 
// A0 = 14, A1 = 15, A2 = 16, A3 = 17, A4 = 18, and A5 = 19.
LiquidCrystal lcd(14, 15, 16, 17, 18, 19);

#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 4
#define START_CONVERSION 5
#define CHIP_SELECT 10
#define MISO 12
#define TOTAL_RAW_BYTES 16

int bytesToRead = TOTAL_RAW_BYTES; 
byte raw[TOTAL_RAW_BYTES]; 
signed long parsed[8];

void setup() { 
 
  pinMode(BUSY, INPUT);
  pinMode(RESET, OUTPUT);
  pinMode(START_CONVERSION, OUTPUT);
  pinMode(MISO, INPUT);

  Serial.begin(115200);
  SPI.begin();
  lcd.begin(20, 4);
 
  digitalWrite(START_CONVERSION, HIGH); 
  digitalWrite(CHIP_SELECT, HIGH);
  digitalWrite(RESET, HIGH);
  delay(1);
  digitalWrite(RESET, LOW);
}

void loop() { 
 
  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.print(parsed[1] * SCALE_FACTOR_2, 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.print(parsed[2] * SCALE_FACTOR_3, 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.print(parsed[3] * SCALE_FACTOR_4, 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;
      }
      }


Go Up