Skip to content

Instantly share code, notes, and snippets.

@Conplug
Created March 25, 2019 13:14
Show Gist options
  • Save Conplug/cab278c662c8cd0046352dc0999a0048 to your computer and use it in GitHub Desktop.
Save Conplug/cab278c662c8cd0046352dc0999a0048 to your computer and use it in GitHub Desktop.
//
// Copyright (c) 2019 Conplug (https://conplug.com.tw)
// Author: Hartman Hsieh
//
// Description :
// None
//
// Connections :
// Plug "DFRobot Gravity I2C DS1307 RTC" at "IIC1" of "NANO_EXP V1.0".
// Plug "MCP3423 V1.0" module at "IIC2" of "NANO_EXP V1.0".
// Plug "SDM_ADP V1.0" module at "SPI1" of "NANO_EXP V1.0".
//
// Required Library :
// https://github.com/uChip/MCP342X
//
//
// IIC Address of MCP3423
//
const int ADC_MCP_ADDRESS = 0x6E;
//
// SD card reader settings
//
const int SD_CARD_CHIP_SELECT_PIN = 6; // SD CARD SPI Chipset Select Pin
const String LogFileName = "vc.txt";
//
// Save one record by the interval, unit is second.
//
const unsigned long UpdateInterval = 5 * 60; // seconds
//
// Resistance value of divider and shunt. unit is ohm.
//
const double RVH = 51.0 * 1000; // Resistance Divider
const double RVL = 1.1 * 1000; // Resistance Divider
const double RI = 0.005; // Shunt Resistance
//
// Current value needs to be corrected
//
const double CurrentCorrection = 1.83333; // current = CurrentCorrection * [original current value]
//
// MCP3423
//
#include <Wire.h>
#include <MCP342X.h>
MCP342X AdcMcp (ADC_MCP_ADDRESS);
//
// SD Card
//
#include <SPI.h>
#include <SD.h>
File SdFile;
Sd2Card Card;
//
// RTC DS1307
//
//char* WeekDays[]={"Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday"};
//
// Global variables
//
static int16_t Result1 = 0, Result2 = 0;
double Voltage = 0;
double Current = 0;
double PreVoltage = 0;
double PreCurrent = 0;
unsigned long CurrentTime = 0, PreviousTime = 0;
int LoopIndex = 0;
void setup() {
Wire.begin(); // Join I2C bus
Serial.begin(9600); // Open serial connection to send info to the host
while (!Serial) {} // wait for Serial comms to become ready
Serial.println("Starting up");
Serial.println("Testing device connection...");
Serial.println(AdcMcp.testConnection() ? "MCP342X connection successful" : "MCP342X connection failed");
//
// Init SD Card
//
pinMode (SD_CARD_CHIP_SELECT_PIN, OUTPUT);
if (!Card.init(SPI_HALF_SPEED, SD_CARD_CHIP_SELECT_PIN)) {
Serial.println("initialization failed. Check: SD Card");
return;
} else {
Serial.println("============= Card Information ==================");
}
//
// Print Card Type
//
Serial.print("Card type: ");
switch (Card.type()) {
case SD_CARD_TYPE_SD1:
Serial.println("SD1");
break;
case SD_CARD_TYPE_SD2:
Serial.println("SD2");
break;
case SD_CARD_TYPE_SDHC:
Serial.println("SDHC");
break;
default:
Serial.println("Unknow");
}
Serial.println("Initializing SD card...");
if (!SD.begin(SD_CARD_CHIP_SELECT_PIN)) {
Serial.println("initialization failed!");
while (1);
}
Serial.println("initialization done.");
} // End of setup()
void loop() {
int Rtc[7] = {0};
unsigned long file_size = 0;
SdFile = SD.open(LogFileName, FILE_READ);
file_size = SdFile.size();
SdFile.close();
//
// Read data from channel 1 for voltage
//
AdcMcp.configure( MCP342X_MODE_CONTINUOUS |
MCP342X_CHANNEL_1 |
MCP342X_SIZE_16BIT |
MCP342X_GAIN_1X
);
AdcMcp.startConversion();
AdcMcp.getResult(&Result1);
//
// From MCP3423 spec.
// http://ww1.microchip.com/downloads/en/DeviceDoc/22088b.pdf
//
// On-Board(MCP3423) Voltage Reference (V REF):
// - Accuracy: 2.048V +- 0.05%
//
// MINIMUM AND MAXIMUM OUTPUT CODES
// +--------------------------------------------------------------+
// | Resolution Setting | Data Rate | Minimum Code | Maximum Code |
// +--------------------------------------------------------------+
// | 16 | 15 SPS | -32768 | 32767 |
// +--------------------------------------------------------------+
//
// Calculate voltage
//
Voltage = (((RVH + RVL) * 2.048) / (RVL * 32767.0)) * Result1;
//
// Read data from channel 2 for current
//
AdcMcp.configure( MCP342X_MODE_CONTINUOUS |
MCP342X_CHANNEL_2 |
MCP342X_SIZE_16BIT |
MCP342X_GAIN_1X
);
AdcMcp.startConversion();
AdcMcp.getResult(&Result2);
//
// See above table and calculate current
//
Current = ((2.048 * Result2) / 32767.0) / RI;
Current *= CurrentCorrection;
if (Current >= -0.02 && Current <= 0.02) Current = 0.0;
//
// If voltage or current changes, save one record.
//
if ((abs(Voltage - PreVoltage) >= 0.02) || (abs(Current - PreCurrent) >= 0.02)) {
SaveToSd(Voltage, Current);
PreVoltage = Voltage;
PreCurrent = Current;
PreviousTime = millis();
}
else {
CurrentTime = millis();
//
// Save one record by the interval, unit is second.
//
if ((PreviousTime == 0) || ((CurrentTime - PreviousTime) > (UpdateInterval * 1000))) {
SaveToSd(Voltage, Current);
PreviousTime = CurrentTime;
}
}
LoopIndex++;
if (LoopIndex >= 99) LoopIndex = 0; // This yields a range of -32,768 to 32,767 (minimum value of -2^15 and a maximum value of (2^15) - 1)
} // End of loop()
void SaveToSd(double Voltage, double Current)
{
int Rtc[7] = {0};
//
// Get data from RTC DS1307
//
RtcGet(Rtc);
SdFile = SD.open(LogFileName, FILE_WRITE);
SdFile.print(Rtc[6]); // YEAR
SdFile.print("-");
PrintDigits(&SdFile, Rtc[5]); // MONTH
SdFile.print("-");
PrintDigits(&SdFile, Rtc[4]); // DATE
SdFile.print(" ");
PrintDigits(&SdFile, Rtc[2]); // HOUR
SdFile.print(":");
PrintDigits(&SdFile, Rtc[1]); // MIN
SdFile.print(":");
PrintDigits(&SdFile, Rtc[0]); // SEC
SdFile.print(",");
SdFile.print(Voltage, 6);
SdFile.print(",");
SdFile.println(Current, 6);
SdFile.flush();
SdFile.close();
Serial.print(Rtc[6]); // YEAR
Serial.print("-");
PrintDigits(&Serial, Rtc[5]); // MONTH
Serial.print("-");
PrintDigits(&Serial, Rtc[4]); // DATE
Serial.print(" ");
PrintDigits(&Serial, Rtc[2]); // HOUR
Serial.print(":");
PrintDigits(&Serial, Rtc[1]); // MIN
Serial.print(":");
PrintDigits(&Serial, Rtc[0]); // SEC
Serial.print(",");
Serial.print(Voltage, 6);
Serial.print(",");
Serial.println(Current, 6);
}
void PrintDigits(Print* pPrint, int digits)
{
if (digits < 10)
pPrint->print('0');
pPrint->print(digits);
}
#define DS1307_CTRL_ID B1101000 // DS1307
bool RtcGet(int* Rtc)
{
uint8_t RtcBcd[7];
Wire.beginTransmission(DS1307_CTRL_ID);
Wire.write((uint8_t)0x00);
Wire.endTransmission();
//
// Read the registers
// Seconds, Minutes, Hours, Day Of Week, Date, Month, Year
//
Wire.requestFrom(DS1307_CTRL_ID, 7);
for(int i = 0; i < 7; i++)
{
RtcBcd[i] = Wire.read();
}
Rtc[0] = Bcd2Dec(RtcBcd[0] & 0x7f); // Seconds
Rtc[1] = Bcd2Dec(RtcBcd[1]); // Minutes
Rtc[2] = Bcd2Dec(RtcBcd[2] & 0x3f); // Hours
Rtc[3] = Bcd2Dec(RtcBcd[3]); // Day Of Week
Rtc[4] = Bcd2Dec(RtcBcd[4]); // Date
Rtc[5] = Bcd2Dec(RtcBcd[5]); // Month
Rtc[6] = Bcd2Dec(RtcBcd[6]) + 2000; // Year
}
//
// Convert Binary Coded Decimal (BCD) to Decimal
//
uint8_t Bcd2Dec(uint8_t Bcd)
{
return ((Bcd / 16 * 10) + (Bcd % 16));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment