mirror of
https://github.com/anklimov/lighthub
synced 2025-12-06 11:49:51 +03:00
mass refactoring
sd_card_code not affects ram and firmware if not enabled
This commit is contained in:
@@ -83,7 +83,7 @@ void USART0_Handler(void) __attribute__((weak));
|
||||
# Platformio command line build instructions
|
||||
[First of all install platformio framework.]( http://docs.platformio.org/en/latest/installation.html) [Good tutorial for fast start in RUSSIAN.](https://geektimes.ru/post/273852/)
|
||||
|
||||
In linux\macOS you can open terminal, navigate to your programming directory, then
|
||||
In linux\OSX you can open terminal, navigate to your programming directory, then
|
||||
|
||||
```bash
|
||||
git clone https://github.com/anklimov/lighthub.git
|
||||
@@ -129,11 +129,6 @@ platformio device monitor -b 115200
|
||||
* MODBUS_DISABLE // disable Modbus support
|
||||
* OWIRE_DISABLE // disable OneWire support
|
||||
|
||||
Look at build_flags_template.sh for customizing.
|
||||
=======
|
||||
|
||||
export PLATFORMIO_BUILD_FLAGS="-DMY_CONFIG_SERVER=192.168.1.1 -DWATCH_DOG_TICKER_DISABLE=1 -DUSE_1W_PIN=49 -DSERIAL_BAUD=115200 -DSD_CARD_INSERTED=1"
|
||||
|
||||
|
||||
# Default compilation behavior:
|
||||
* Config server: lazyhome.ru
|
||||
@@ -147,5 +142,4 @@ export PLATFORMIO_BUILD_FLAGS="-DMY_CONFIG_SERVER=192.168.1.1 -DWATCH_DOG_TICKER
|
||||
* DMX support enabled
|
||||
* Modbus support enabled
|
||||
* OneWire support enabled
|
||||
=======
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@ e-mail anklimov@gmail.com
|
||||
#define fmPar SERIAL_8N1
|
||||
|
||||
short modbusBusy = 0;
|
||||
extern aJsonObject *modbusitem;
|
||||
extern aJsonObject *modbusItem;
|
||||
|
||||
|
||||
int modbusSet(int addr, uint16_t _reg, int _mask, uint16_t value);
|
||||
@@ -934,12 +934,12 @@ int Item::checkModbus() {
|
||||
modbusBusy = 0;
|
||||
|
||||
// Looking 1 step ahead for modbus item, which uses same register
|
||||
Item nextItem(modbusitem->next);
|
||||
if (modbusitem && nextItem.isValid() && nextItem.itemType == CH_MODBUS && nextItem.getArg(0) == addr &&
|
||||
Item nextItem(modbusItem->next);
|
||||
if (modbusItem && nextItem.isValid() && nextItem.itemType == CH_MODBUS && nextItem.getArg(0) == addr &&
|
||||
nextItem.getArg(1) == reg) {
|
||||
nextItem.checkModbus(data);
|
||||
modbusitem = modbusitem->next;
|
||||
if (!modbusitem) modbusitem = items->child;
|
||||
modbusItem = modbusItem->next;
|
||||
if (!modbusItem) modbusItem = items->child;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -57,119 +57,20 @@ DMX-OUT deploy on USART1
|
||||
Config webserver
|
||||
|
||||
*/
|
||||
#if defined(__ESP__)
|
||||
#include <FS.h> //this needs to be first, or it all crashes and burns...
|
||||
#endif
|
||||
|
||||
|
||||
#include "main.h"
|
||||
|
||||
// Configuration of drivers enabled
|
||||
#include "options.h"
|
||||
|
||||
|
||||
#include <PubSubClient.h>
|
||||
#include <SPI.h>
|
||||
#include "utils.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <ModbusMaster.h>
|
||||
#include "aJSON.h"
|
||||
#include <Cmd.h>
|
||||
#include "stdarg.h"
|
||||
|
||||
#if defined(__AVR__)
|
||||
|
||||
#include "HTTPClient.h"
|
||||
#include <avr/pgmspace.h>
|
||||
#include <avr/wdt.h>
|
||||
|
||||
#define wdt_en() wdt_enable(WDTO_8S)
|
||||
#define wdt_dis() wdt_disable()
|
||||
#define wdt_res() wdt_reset()
|
||||
#else
|
||||
|
||||
#include <ArduinoHttpClient.h>
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(WATCH_DOG_TICKER_DISABLE)
|
||||
#define wdt_en() wdt_disable()
|
||||
#define wdt_dis() wdt_disable()
|
||||
#define wdt_res() wdt_disable()
|
||||
#endif
|
||||
|
||||
#if defined(__SAM3X8E__)
|
||||
|
||||
#include <DueFlashStorage.h>
|
||||
|
||||
DueFlashStorage EEPROM;
|
||||
|
||||
#include <watchdog.h>
|
||||
|
||||
#define wdt_res() watchdogReset()
|
||||
#define wdt_en()
|
||||
#define wdt_dis()
|
||||
|
||||
#else
|
||||
|
||||
#include <EEPROM.h>
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(__ESP__)
|
||||
#include "esp.h"
|
||||
#define wdt_res()
|
||||
#define wdt_en()
|
||||
#define wdt_dis()
|
||||
|
||||
#else
|
||||
|
||||
#include "Dhcp.h"
|
||||
|
||||
#ifdef Wiz5500
|
||||
#include <Ethernet2.h>
|
||||
#else
|
||||
|
||||
#include <Ethernet.h>
|
||||
|
||||
#endif
|
||||
|
||||
EthernetClient ethClient;
|
||||
#endif
|
||||
|
||||
#ifdef _owire
|
||||
|
||||
#include "owTerm.h"
|
||||
|
||||
#if defined(__AVR__)
|
||||
EthernetClient ethClient;
|
||||
#endif
|
||||
|
||||
#if defined(_dmxin) || defined(_dmxout) || defined (_artnet)
|
||||
|
||||
#include "dmx.h"
|
||||
|
||||
#endif
|
||||
|
||||
#include "item.h"
|
||||
#include "inputs.h"
|
||||
|
||||
#ifdef _artnet
|
||||
|
||||
#include <Artnet.h>
|
||||
|
||||
extern Artnet *artnet;
|
||||
#endif
|
||||
|
||||
#ifdef SD_CARD_INSERTED
|
||||
#include "sd_card_w5100.h"
|
||||
#endif
|
||||
|
||||
// Hardcoded definitions
|
||||
//Thermostate histeresys
|
||||
#define GIST 2
|
||||
//#define serverip "192.168.88.2"
|
||||
//IPAddress server(192, 168, 88, 2); //TODO - configure it
|
||||
|
||||
//const char inprefix[] PROGMEM = "/myhome/in/"
|
||||
const char outprefix[] PROGMEM = OUTTOPIC;
|
||||
const char inprefix[] PROGMEM = INTOPIC;
|
||||
|
||||
@@ -182,12 +83,12 @@ aJsonObject *modbusArr = NULL;
|
||||
aJsonObject *owArr = NULL;
|
||||
aJsonObject *dmxArr = NULL;
|
||||
|
||||
unsigned long modbuscheck = 0;
|
||||
unsigned long incheck = 0;
|
||||
unsigned long nextModbusCheck = 0;
|
||||
unsigned long nextInputCheck = 0;
|
||||
unsigned long lanCheck = 0;
|
||||
unsigned long thermocheck = 0;
|
||||
unsigned long nextThermostatCheck = 0;
|
||||
|
||||
aJsonObject *modbusitem = NULL;
|
||||
aJsonObject *modbusItem = NULL;
|
||||
|
||||
bool owReady = false;
|
||||
int lanStatus = 0;
|
||||
@@ -205,9 +106,10 @@ PubSubClient mqttClient(ethClient);
|
||||
void watchdogSetup(void) {} //Do not remove - strong re-definition WDT Init for DUE
|
||||
|
||||
// MQTT Callback routine
|
||||
#define sublen 20
|
||||
#define topiclen 20
|
||||
void callback(char *topic, byte *payload, unsigned int length) {
|
||||
#define MQTT_SUBJECT_LENGTH 20
|
||||
#define MQTT_TOPIC_LENGTH 20
|
||||
|
||||
void mqttCallback(char *topic, byte *payload, unsigned int length) {
|
||||
payload[length] = 0;
|
||||
Serial.print(F("\n["));
|
||||
Serial.print(topic);
|
||||
@@ -218,7 +120,7 @@ void callback(char *topic, byte *payload, unsigned int length) {
|
||||
Serial.println(F("OOM!"));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
for (int i = 0; i < length; i++) {
|
||||
Serial.print((char) payload[i]);
|
||||
}
|
||||
@@ -226,25 +128,26 @@ void callback(char *topic, byte *payload, unsigned int length) {
|
||||
|
||||
boolean retaining = (lanStatus == 4); //Todo - named constant
|
||||
//Check if topic = Command topic
|
||||
short intopic=0;
|
||||
short intopic = 0;
|
||||
{
|
||||
char buf[topiclen+1];
|
||||
strncpy_P(buf,inprefix,sizeof(buf));
|
||||
intopic = strncmp(topic,buf,strlen(inprefix));
|
||||
char buf[MQTT_TOPIC_LENGTH + 1];
|
||||
strncpy_P(buf, inprefix, sizeof(buf));
|
||||
intopic = strncmp(topic, buf, strlen(inprefix));
|
||||
}
|
||||
|
||||
// in Retaining status - trying to restore previous state from retained output topic. Retained input topics are not relevant.
|
||||
if (retaining && !intopic) {
|
||||
Serial.println(F("Skipping.."));
|
||||
return;
|
||||
Serial.println(F("Skipping.."));
|
||||
return;
|
||||
}
|
||||
|
||||
char subtopic[sublen] = "";
|
||||
|
||||
char subtopic[MQTT_SUBJECT_LENGTH] = "";
|
||||
int cmd = 0;
|
||||
|
||||
|
||||
cmd = txt2cmd((char *) payload);
|
||||
char *t;
|
||||
if (t = strrchr(topic, '/')) strncpy(subtopic, t + 1, sublen - 1);
|
||||
if (t = strrchr(topic, '/'))
|
||||
strncpy(subtopic, t + 1, MQTT_SUBJECT_LENGTH - 1);
|
||||
|
||||
|
||||
|
||||
@@ -286,8 +189,9 @@ void callback(char *topic, byte *payload, unsigned int length) {
|
||||
case CMD_ON:
|
||||
|
||||
if (item.getEnableCMD(500) || lanStatus == 4)
|
||||
item.Ctrl(cmd, 0, NULL, !retaining); //Accept ON command not earlier then 500 ms after set settings (Homekit hack)
|
||||
else Serial.println("on Skipped");
|
||||
item.Ctrl(cmd, 0, NULL,
|
||||
!retaining); //Accept ON command not earlier then 500 ms after set settings (Homekit hack)
|
||||
else Serial.println(F("on Skipped"));
|
||||
|
||||
break;
|
||||
default: //some known command
|
||||
@@ -303,7 +207,6 @@ void callback(char *topic, byte *payload, unsigned int length) {
|
||||
void printIPAddress() {
|
||||
Serial.print(F("My IP address: "));
|
||||
for (byte thisByte = 0; thisByte < 4; thisByte++) {
|
||||
// print the value of each byte of the IP address:
|
||||
Serial.print(Ethernet.localIP()[thisByte], DEC);
|
||||
Serial.print(F("."));
|
||||
}
|
||||
@@ -313,13 +216,11 @@ void printIPAddress() {
|
||||
#endif
|
||||
|
||||
void printMACAddress() {
|
||||
Serial.print(F("My mac address: "));
|
||||
Serial.print(F("Configured MAC:"));
|
||||
for (byte thisByte = 0; thisByte < 6; thisByte++) {
|
||||
// print the value of each byte of the IP address:
|
||||
Serial.print(mac[thisByte], HEX);
|
||||
Serial.print(F(":"));
|
||||
}
|
||||
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
@@ -328,9 +229,6 @@ void restoreState() {
|
||||
//mqttClient.publish("/myhome/out/RestoreState", "ON");
|
||||
};
|
||||
|
||||
|
||||
int getConfig(int arg_cnt, char **args);
|
||||
|
||||
int lanLoop() {
|
||||
|
||||
#ifdef NOETHER
|
||||
@@ -403,17 +301,17 @@ if((wifiMulti.run() == WL_CONNECTED)) lanStatus=1;
|
||||
|
||||
|
||||
// ... Temporary subscribe to status topic
|
||||
char buf[topiclen];
|
||||
|
||||
strncpy_P(buf,outprefix,sizeof(buf));
|
||||
strncat(buf,"#",sizeof(buf));
|
||||
char buf[MQTT_TOPIC_LENGTH];
|
||||
|
||||
strncpy_P(buf, outprefix, sizeof(buf));
|
||||
strncat(buf, "#", sizeof(buf));
|
||||
mqttClient.subscribe(buf);
|
||||
|
||||
|
||||
//Subscribing for command topics
|
||||
strncpy_P(buf,inprefix,sizeof(buf));
|
||||
strncat(buf,"#",sizeof(buf));
|
||||
mqttClient.subscribe(buf);
|
||||
|
||||
strncpy_P(buf, inprefix, sizeof(buf));
|
||||
strncat(buf, "#", sizeof(buf));
|
||||
mqttClient.subscribe(buf);
|
||||
|
||||
//restoreState();
|
||||
// if (_once) {DMXput(); _once=0;}
|
||||
lanStatus = 4;
|
||||
@@ -431,19 +329,19 @@ if((wifiMulti.run() == WL_CONNECTED)) lanStatus=1;
|
||||
}
|
||||
|
||||
case 4: //retaining ... Collecting
|
||||
if (millis() > lanCheck) {
|
||||
char buf[topiclen];
|
||||
|
||||
//Unsubscribe from status topics..
|
||||
strncpy_P(buf,outprefix,sizeof(buf));
|
||||
strncat(buf,"#",sizeof(buf));
|
||||
mqttClient.unsubscribe(buf);
|
||||
|
||||
lanStatus = 3;
|
||||
Serial.println(F("Accepting commands..."));
|
||||
break;
|
||||
}
|
||||
|
||||
if (millis() > lanCheck) {
|
||||
char buf[MQTT_TOPIC_LENGTH];
|
||||
|
||||
//Unsubscribe from status topics..
|
||||
strncpy_P(buf, outprefix, sizeof(buf));
|
||||
strncat(buf, "#", sizeof(buf));
|
||||
mqttClient.unsubscribe(buf);
|
||||
|
||||
lanStatus = 3;
|
||||
Serial.println(F("Accepting commands..."));
|
||||
break;
|
||||
}
|
||||
|
||||
case 3: //operation
|
||||
if (!mqttClient.connected()) lanStatus = 2;
|
||||
break;
|
||||
@@ -597,11 +495,10 @@ void Changed(int i, DeviceAddress addr, int val) {
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif //_owire
|
||||
|
||||
void modbusIdle(void);
|
||||
|
||||
void _handleHelp(int arg_cnt, char **args)
|
||||
void cmdFunctionHelp(int arg_cnt, char **args)
|
||||
//(char* tokens)
|
||||
{
|
||||
Serial.println(F("Use the commands: 'help' - this text\n"
|
||||
@@ -612,29 +509,27 @@ void _handleHelp(int arg_cnt, char **args)
|
||||
"'kill' - test watchdog"));
|
||||
}
|
||||
|
||||
void _kill(int arg_cnt, char **args) {
|
||||
void cmdFunctionKill(int arg_cnt, char **args) {
|
||||
for (short i = 17; i > 0; i--) {
|
||||
delay(1000);
|
||||
Serial.println(i);
|
||||
};
|
||||
}
|
||||
|
||||
#define EEPROM_offset 32+6
|
||||
|
||||
void applyConfig() {
|
||||
int arrayItemValue, itemsCount;
|
||||
//DMX out is configured
|
||||
aJsonObject *dmxoutArr = aJson.getObjectItem(root, "dmx");
|
||||
#ifdef _dmxout
|
||||
int maxChannels;
|
||||
aJsonObject *dmxoutArr = aJson.getObjectItem(root, "dmx");
|
||||
if (dmxoutArr && aJson.getArraySize(dmxoutArr) == 2) {
|
||||
DMXoutSetup(arrayItemValue = aJson.getArrayItem(dmxoutArr, 1)->valueint,
|
||||
DMXoutSetup(maxChannels = aJson.getArrayItem(dmxoutArr, 1)->valueint,
|
||||
aJson.getArrayItem(dmxoutArr, 0)->valueint);
|
||||
Serial.print(F("DMX out started. Channels: "));
|
||||
Serial.println(arrayItemValue);
|
||||
Serial.println(maxChannels);
|
||||
}
|
||||
#endif
|
||||
//DMX in is configured
|
||||
|
||||
#ifdef _dmxin
|
||||
int itemsCount;
|
||||
dmxArr = aJson.getObjectItem(root, "dmxin");
|
||||
if (dmxArr && (itemsCount = aJson.getArraySize(dmxArr))) {
|
||||
DMXinSetup(itemsCount * 4);
|
||||
@@ -643,22 +538,38 @@ void applyConfig() {
|
||||
}
|
||||
#endif
|
||||
|
||||
items = aJson.getObjectItem(root, "items");
|
||||
modbusitem = items->child;
|
||||
inputs = aJson.getObjectItem(root, "in");
|
||||
|
||||
#ifdef _modbus
|
||||
modbusArr = aJson.getObjectItem(root, "modbus");
|
||||
#endif
|
||||
|
||||
mqttArr = aJson.getObjectItem(root, "mqtt");
|
||||
|
||||
#ifdef _owire
|
||||
owArr = aJson.getObjectItem(root, "ow");
|
||||
#endif
|
||||
|
||||
Serial.println(F("Configured:"));
|
||||
#ifdef _owire
|
||||
if (owArr && !owReady) {
|
||||
aJsonObject *item = owArr->child;
|
||||
owReady = owSetup(&Changed);
|
||||
while (item) {
|
||||
if ((item->type == aJson_Object)) {
|
||||
DeviceAddress addr;
|
||||
//Serial.print(F("Add:")),Serial.println(item->name);
|
||||
SetAddr(item->name, addr);
|
||||
owAdd(addr);
|
||||
}
|
||||
item = item->next;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
items = aJson.getObjectItem(root, "items");
|
||||
modbusItem = items->child;
|
||||
inputs = aJson.getObjectItem(root, "in");
|
||||
mqttArr = aJson.getObjectItem(root, "mqtt");
|
||||
printConfigSummary();
|
||||
}
|
||||
|
||||
void printConfigSummary() {
|
||||
Serial.println(F("Configured:"));
|
||||
Serial.print(F("items "));
|
||||
printBool(items);
|
||||
Serial.print(F("inputs "));
|
||||
@@ -669,27 +580,9 @@ void applyConfig() {
|
||||
printBool(mqttArr);
|
||||
Serial.print(F("1-wire "));
|
||||
printBool(owArr);
|
||||
|
||||
#ifdef _owire
|
||||
if (owArr && !owReady) {
|
||||
aJsonObject *item = owArr->child;
|
||||
owReady = owSetup(&Changed);
|
||||
|
||||
while (item) {
|
||||
if ((item->type == aJson_Object)) {
|
||||
DeviceAddress addr;
|
||||
//Serial.print(F("Add:")),Serial.println(item->name);
|
||||
SetAddr(item->name, addr);
|
||||
owAdd(addr);
|
||||
}
|
||||
item = item->next;
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void _loadConfig(int arg_cnt, char **args) {
|
||||
void cmdFunctionLoad(int arg_cnt, char **args) {
|
||||
loadConfigFromEEPROM(arg_cnt, args);
|
||||
restoreState();
|
||||
}
|
||||
@@ -720,7 +613,7 @@ int loadConfigFromEEPROM(int arg_cnt, char **args)
|
||||
}
|
||||
}
|
||||
|
||||
void _mqttConfigRequest(int arg_cnt, char **args) {
|
||||
void cmdFunctionReq(int arg_cnt, char **args) {
|
||||
mqttConfigRequest(arg_cnt, args);
|
||||
restoreState();
|
||||
}
|
||||
@@ -761,7 +654,7 @@ int mqttConfigResp(char *as) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
void _saveConfigToEEPROM(int arg_cnt, char **args)
|
||||
void cmdFunctionSave(int arg_cnt, char **args)
|
||||
//(char* tokens)
|
||||
{
|
||||
aJsonEEPROMStream jsonEEPROMStream = aJsonEEPROMStream(EEPROM_offset);
|
||||
@@ -772,7 +665,7 @@ void _saveConfigToEEPROM(int arg_cnt, char **args)
|
||||
}
|
||||
|
||||
|
||||
void _setMacAddress(int arg_cnt, char **args) {
|
||||
void cmdFunctionSetMac(int arg_cnt, char **args) {
|
||||
|
||||
//Serial.print("Got:");
|
||||
//Serial.println(args[1]);
|
||||
@@ -792,7 +685,7 @@ void _setMacAddress(int arg_cnt, char **args) {
|
||||
Serial.println(F("Updated"));
|
||||
}
|
||||
|
||||
void _getConfig(int arg_cnt, char **args) {
|
||||
void cmdFunctionGet(int arg_cnt, char **args) {
|
||||
getConfig(arg_cnt, args);
|
||||
restoreState();
|
||||
}
|
||||
@@ -938,63 +831,27 @@ void postTransmission() {
|
||||
//modbusSerial.flush();
|
||||
digitalWrite(TXEnablePin, 0);
|
||||
}
|
||||
//#define PIO_SRC_REV commit 8034a6b765229d94a94d90fd08dd9588acf5f3da Author: livello <livello@bk.ru> Date: Wed Mar 28 02:35:50 2018 +0300 refactoring
|
||||
|
||||
void setup_main() {
|
||||
cmdInit(uint32_t(SERIAL_BAUD));
|
||||
|
||||
Serial.print(F("\nLazyhome.ru LightHub controller "));
|
||||
Serial.println(F(QUOTE(PIO_SRC_REV)));
|
||||
#ifdef WATCH_DOG_TICKER_DISABLE
|
||||
Serial.println(F("WATCHDOG TICKER DISABLED"));
|
||||
#endif
|
||||
|
||||
#ifdef DISABLE_FREERAM_PRINT
|
||||
Serial.println(F("FreeRam printing DISABLED"));
|
||||
#endif
|
||||
setupCmdArduino();
|
||||
printFirmwareVersionAndBuildOptions();
|
||||
|
||||
#ifdef SD_CARD_INSERTED
|
||||
sd_card_w5100_setup();
|
||||
#endif
|
||||
|
||||
cmdAdd("help", _handleHelp);
|
||||
cmdAdd("save", _saveConfigToEEPROM);
|
||||
cmdAdd("load", _loadConfig);
|
||||
cmdAdd("get", _getConfig);
|
||||
cmdAdd("set", _setMacAddress);
|
||||
cmdAdd("kill", _kill);
|
||||
cmdAdd("req", _mqttConfigRequest);
|
||||
|
||||
|
||||
#ifdef __ESP__
|
||||
espSetup();
|
||||
#endif
|
||||
|
||||
short macvalid = 0;
|
||||
|
||||
#ifdef FIRMWARE_MAC
|
||||
byte firmwareMacAddress[6] = FIRMWARE_MAC;
|
||||
#else
|
||||
byte firmwareMacAddress[6];
|
||||
const char* macStr = QUOTE(CUSTOM_FIRMWARE_MAC);
|
||||
parseBytes(macStr, ':', firmwareMacAddress, 6, 16);
|
||||
#endif
|
||||
|
||||
for (short i = 0; i < 6; i++) {
|
||||
mac[i] = EEPROM.read(i);
|
||||
if (mac[i] != 0 && mac[i] != 0xff) macvalid = 1;
|
||||
}
|
||||
if (!macvalid) {
|
||||
Serial.println(F("Invalid MAC: set firmware's MAC"));
|
||||
memcpy(mac, firmwareMacAddress, 6);
|
||||
}
|
||||
printMACAddress();
|
||||
setupMacAddress();
|
||||
|
||||
loadConfigFromEEPROM(0, NULL);
|
||||
|
||||
#ifdef _modbus
|
||||
pinMode(TXEnablePin, OUTPUT);
|
||||
modbusSerial.begin(9600);
|
||||
|
||||
modbusSerial.begin(MODBUS_SERIAL_BAUD);
|
||||
node.idle(&modbusIdle);
|
||||
// Callbacks allow us to configure the RS485 transceiver correctly
|
||||
node.preTransmission(preTransmission);
|
||||
@@ -1002,33 +859,83 @@ void setup_main() {
|
||||
#endif
|
||||
|
||||
delay(20);
|
||||
|
||||
owReady = 0;
|
||||
|
||||
#ifdef _owire
|
||||
if (net) net->idle(&owIdle);
|
||||
#endif
|
||||
|
||||
//client.setServer(server, 1883);
|
||||
mqttClient.setCallback(callback);
|
||||
|
||||
mqttClient.setCallback(mqttCallback);
|
||||
|
||||
#ifdef _artnet
|
||||
ArtnetSetup();
|
||||
#endif
|
||||
|
||||
#if defined(__SAM3X8E__)
|
||||
// checkForRemoteSketchUpdate();
|
||||
//TODO: checkForRemoteSketchUpdate();
|
||||
}
|
||||
|
||||
void printFirmwareVersionAndBuildOptions() {
|
||||
Serial.print(F("\nLazyhome.ru LightHub controller "));
|
||||
Serial.println(F(QUOTE(PIO_SRC_REV)));
|
||||
#ifdef WATCH_DOG_TICKER_DISABLE
|
||||
Serial.println(F("(-)WATCHDOG"));
|
||||
#else
|
||||
Serial.println(F("(+)WATCHDOG"));
|
||||
#endif
|
||||
Serial.print(F("Config server:"));
|
||||
Serial.println(F(CONFIG_SERVER));
|
||||
Serial.print(F("Firmware MAC Address "));
|
||||
#ifdef DEFAULT_FIRMWARE_MAC
|
||||
Serial.println(F(Q(DEFAULT_FIRMWARE_MAC)));
|
||||
#endif
|
||||
#ifdef CUSTOM_FIRMWARE_MAC
|
||||
Serial.println(F(QUOTE(CUSTOM_FIRMWARE_MAC)));
|
||||
#endif
|
||||
printMACAddress();
|
||||
|
||||
#ifdef DISABLE_FREERAM_PRINT
|
||||
Serial.println(F("(-)FreeRam printing"));
|
||||
#else
|
||||
Serial.println(F("(+)FreeRam printing"));
|
||||
#endif
|
||||
|
||||
|
||||
}
|
||||
|
||||
void setupMacAddress() {
|
||||
#ifdef DEFAULT_FIRMWARE_MAC
|
||||
byte firmwareMacAddress[6] = DEFAULT_FIRMWARE_MAC;
|
||||
#else
|
||||
byte firmwareMacAddress[6];
|
||||
const char *macStr = QUOTE(CUSTOM_FIRMWARE_MAC);
|
||||
parseBytes(macStr, ':', firmwareMacAddress, 6, 16);
|
||||
#endif
|
||||
|
||||
bool isMacValid = false;
|
||||
for (short i = 0; i < 6; i++) {
|
||||
mac[i] = EEPROM.read(i);
|
||||
if (mac[i] != 0 && mac[i] != 0xff) isMacValid = true;
|
||||
}
|
||||
if (!isMacValid) {
|
||||
Serial.println(F("Invalid MAC: set firmware's MAC"));
|
||||
memcpy(mac, firmwareMacAddress, 6);
|
||||
}
|
||||
printMACAddress();
|
||||
}
|
||||
|
||||
void setupCmdArduino() {
|
||||
cmdInit(uint32_t(SERIAL_BAUD));
|
||||
cmdAdd("help", cmdFunctionHelp);
|
||||
cmdAdd("save", cmdFunctionSave);
|
||||
cmdAdd("load", cmdFunctionLoad);
|
||||
cmdAdd("get", cmdFunctionGet);
|
||||
cmdAdd("set", cmdFunctionSetMac);
|
||||
cmdAdd("kill", cmdFunctionKill);
|
||||
cmdAdd("req", cmdFunctionReq);
|
||||
}
|
||||
|
||||
void loop_main() {
|
||||
wdt_res();
|
||||
|
||||
//commandLine.update();
|
||||
cmdPoll();
|
||||
if (lanLoop() > 1) {
|
||||
mqttClient.loop();
|
||||
@@ -1047,8 +954,6 @@ void loop_main() {
|
||||
#endif
|
||||
// if (lastpacket && (lastpacket%10==0)) Serial.println(lastpacket);
|
||||
|
||||
|
||||
|
||||
#ifdef _modbus
|
||||
if (modbusArr && items) modbusLoop();
|
||||
#endif
|
||||
@@ -1062,19 +967,16 @@ void loop_main() {
|
||||
#if defined (_espdmx)
|
||||
dmxout.update();
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
// Idle handlers
|
||||
void owIdle(void) {
|
||||
#ifdef _artnet
|
||||
if (artnet) artnet->read();
|
||||
#endif
|
||||
|
||||
wdt_res();
|
||||
return;///
|
||||
return; //TODO: unreached code
|
||||
Serial.print(F("o"));
|
||||
|
||||
if (lanLoop() == 1) mqttClient.loop();
|
||||
//if (owReady) owLoop();
|
||||
|
||||
@@ -1085,14 +987,9 @@ void owIdle(void) {
|
||||
#if defined (_espdmx)
|
||||
dmxout.update();
|
||||
#endif
|
||||
|
||||
//modbusLoop();
|
||||
}
|
||||
|
||||
|
||||
void modbusIdle(void) {
|
||||
//Serial.print("m");
|
||||
|
||||
wdt_res();
|
||||
if (lanLoop() > 1) {
|
||||
mqttClient.loop();
|
||||
@@ -1101,7 +998,6 @@ void modbusIdle(void) {
|
||||
#endif
|
||||
}
|
||||
|
||||
//if (owReady) owLoop();
|
||||
#ifdef _dmxin
|
||||
DMXCheck();
|
||||
#endif
|
||||
@@ -1109,22 +1005,11 @@ void modbusIdle(void) {
|
||||
#if defined (_espdmx)
|
||||
dmxout.update();
|
||||
#endif
|
||||
|
||||
//modbusloop();
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Loops
|
||||
|
||||
|
||||
|
||||
void inputLoop(void) {
|
||||
|
||||
if (millis() > incheck) {
|
||||
|
||||
if (millis() > nextInputCheck) {
|
||||
aJsonObject *input = inputs->child;
|
||||
|
||||
while (input) {
|
||||
if ((input->type == aJson_Object)) {
|
||||
Input in(input);
|
||||
@@ -1132,35 +1017,31 @@ void inputLoop(void) {
|
||||
}
|
||||
input = input->next;
|
||||
}
|
||||
|
||||
|
||||
incheck = millis() + 50;
|
||||
|
||||
nextInputCheck = millis() + INTERVAL_CHECK_INPUT;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void modbusLoop(void) {
|
||||
boolean done = false;
|
||||
if (millis() > modbuscheck) {
|
||||
while (modbusitem && !done) {
|
||||
if (modbusitem->type == aJson_Array) {
|
||||
switch (aJson.getArrayItem(modbusitem, 0)->valueint) {
|
||||
if (millis() > nextModbusCheck) {
|
||||
while (modbusItem && !done) {
|
||||
if (modbusItem->type == aJson_Array) {
|
||||
switch (aJson.getArrayItem(modbusItem, 0)->valueint) {
|
||||
case CH_MODBUS:
|
||||
//case CH_VCTEMP:
|
||||
case CH_VC: {
|
||||
Item it(modbusitem);
|
||||
Item it(modbusItem);
|
||||
it.Poll();
|
||||
modbuscheck = millis() + 2000;
|
||||
nextModbusCheck = millis() + INTERVAL_CHECK_MODBUS;
|
||||
done = true;
|
||||
break; //case;
|
||||
}
|
||||
} //switch
|
||||
|
||||
}//if
|
||||
modbusitem = modbusitem->next;
|
||||
if (!modbusitem) {
|
||||
modbusitem = items->child;
|
||||
modbusItem = modbusItem->next;
|
||||
if (!modbusItem) {
|
||||
modbusItem = items->child;
|
||||
return;
|
||||
} //start from 1-st element
|
||||
} //while
|
||||
@@ -1168,75 +1049,71 @@ void modbusLoop(void) {
|
||||
}
|
||||
|
||||
|
||||
// To be refactored
|
||||
//TODO: refactoring
|
||||
|
||||
void thermoLoop(void) {
|
||||
#define T_ATTEMPTS 200
|
||||
#define IET_TEMP 0
|
||||
#define IET_ATTEMPTS 1
|
||||
if (millis() < nextThermostatCheck)
|
||||
return;
|
||||
|
||||
if (millis() > thermocheck) {
|
||||
bool thermostatCheckPrinted = false;
|
||||
aJsonObject *item = items->child;
|
||||
bool thermostatCheckPrinted = false;
|
||||
aJsonObject *item = items->child;
|
||||
|
||||
while (item) {
|
||||
if ((item->type == aJson_Array) && (aJson.getArrayItem(item, 0)->valueint == CH_THERMO) &&
|
||||
(aJson.getArraySize(item) > 4)) {
|
||||
int pin = aJson.getArrayItem(item, I_ARG)->valueint;
|
||||
int temp = aJson.getArrayItem(item, I_VAL)->valueint;
|
||||
while (item) {
|
||||
if ((item->type == aJson_Array) && (aJson.getArrayItem(item, 0)->valueint == CH_THERMO) &&
|
||||
(aJson.getArraySize(item) > 4)) {
|
||||
int itemPin = aJson.getArrayItem(item, I_ARG)->valueint;
|
||||
int itemTempSetting = aJson.getArrayItem(item, I_VAL)->valueint;
|
||||
int itemCommand = aJson.getArrayItem(item, I_CMD)->valueint;
|
||||
aJsonObject *itemExtensionArray = aJson.getArrayItem(item, I_EXT);
|
||||
|
||||
int cmd = aJson.getArrayItem(item, I_CMD)->valueint;
|
||||
|
||||
aJsonObject *extArr = aJson.getArrayItem(item, I_EXT);
|
||||
|
||||
if (extArr && (aJson.getArraySize(extArr) > 1)) {
|
||||
int curtemp = aJson.getArrayItem(extArr, IET_TEMP)->valueint;
|
||||
if (!aJson.getArrayItem(extArr, IET_ATTEMPTS)->valueint) {
|
||||
Serial.print(item->name);
|
||||
Serial.println(F(" Expired"));
|
||||
|
||||
} else {
|
||||
if (!(--aJson.getArrayItem(extArr, IET_ATTEMPTS)->valueint))
|
||||
mqttClient.publish("/alarm", item->name);
|
||||
|
||||
}
|
||||
thermostatCheckPrinted = true;
|
||||
if (itemExtensionArray && (aJson.getArraySize(itemExtensionArray) > 1)) {
|
||||
int curtemp = aJson.getArrayItem(itemExtensionArray, IET_TEMP)->valueint;
|
||||
if (!aJson.getArrayItem(itemExtensionArray, IET_ATTEMPTS)->valueint) {
|
||||
Serial.print(item->name);
|
||||
Serial.print(F(" Set:"));
|
||||
Serial.print(temp);
|
||||
Serial.print(F(" Curtemp:"));
|
||||
Serial.print(curtemp);
|
||||
Serial.print(F(" cmd:"));
|
||||
Serial.print(cmd),
|
||||
Serial.println(F(" Expired"));
|
||||
|
||||
pinMode(pin, OUTPUT);
|
||||
if (cmd == CMD_OFF || cmd == CMD_HALT || aJson.getArrayItem(extArr, IET_ATTEMPTS)->valueint == 0) {
|
||||
digitalWrite(pin, LOW);
|
||||
} else {
|
||||
if (!(--aJson.getArrayItem(itemExtensionArray, IET_ATTEMPTS)->valueint))
|
||||
mqttClient.publish("/alarm", item->name);
|
||||
|
||||
}
|
||||
thermostatCheckPrinted = true;
|
||||
Serial.print(item->name);
|
||||
Serial.print(F(" Set:"));
|
||||
Serial.print(itemTempSetting);
|
||||
Serial.print(F(" Curtemp:"));
|
||||
Serial.print(curtemp);
|
||||
Serial.print(F(" cmd:"));
|
||||
Serial.print(itemCommand),
|
||||
|
||||
pinMode(itemPin, OUTPUT);
|
||||
if (itemCommand == CMD_OFF || itemCommand == CMD_HALT ||
|
||||
aJson.getArrayItem(itemExtensionArray, IET_ATTEMPTS)->valueint == 0) {
|
||||
digitalWrite(itemPin, LOW);
|
||||
Serial.println(F(" OFF"));
|
||||
} else {
|
||||
if (curtemp + THERMO_GIST_CELSIUS < itemTempSetting) {
|
||||
digitalWrite(itemPin, HIGH);
|
||||
Serial.println(F(" ON"));
|
||||
} //too cold
|
||||
else if (itemTempSetting <= curtemp) {
|
||||
digitalWrite(itemPin, LOW);
|
||||
Serial.println(F(" OFF"));
|
||||
} else {
|
||||
if (curtemp + GIST < temp) {
|
||||
digitalWrite(pin, HIGH);
|
||||
Serial.println(F(" ON"));
|
||||
} //too cold
|
||||
else if (temp <= curtemp) {
|
||||
digitalWrite(pin, LOW);
|
||||
Serial.println(F(" OFF"));
|
||||
} //Reached settings
|
||||
else Serial.println(F(" --")); // Nothing to do
|
||||
}
|
||||
} //Reached settings
|
||||
else Serial.println(F(" --")); // Nothing to do
|
||||
}
|
||||
}
|
||||
item = item->next;
|
||||
}
|
||||
item = item->next;
|
||||
}
|
||||
|
||||
thermocheck = millis() + 5000;
|
||||
nextThermostatCheck = millis() + THERMOSTAT_CHECK_PERIOD;
|
||||
|
||||
#ifndef DISABLE_FREERAM_PRINT
|
||||
(thermostatCheckPrinted) ? Serial.print(F("\nfree:")) : Serial.print(F(" "));
|
||||
Serial.print(freeRam());
|
||||
Serial.print(" ");
|
||||
(thermostatCheckPrinted) ? Serial.print(F("\nfree:")) : Serial.print(F(" "));
|
||||
Serial.print(freeRam());
|
||||
Serial.print(" ");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
173
lighthub/main.h
173
lighthub/main.h
@@ -1,56 +1,181 @@
|
||||
//
|
||||
// Created by livello on 13.03.18.
|
||||
//
|
||||
#include "options.h"
|
||||
|
||||
#ifndef LIGHTHUB_MAIN_H
|
||||
#define LIGHTHUB_MAIN_H
|
||||
|
||||
#define TXEnablePin 13
|
||||
|
||||
#ifndef SERIAL_BAUD
|
||||
#define SERIAL_BAUD 115200
|
||||
#if defined(__SAM3X8E__)
|
||||
#define wdt_res() watchdogReset()
|
||||
#define wdt_en()
|
||||
#define wdt_dis()
|
||||
#endif
|
||||
|
||||
#ifndef CUSTOM_FIRMWARE_MAC
|
||||
#define FIRMWARE_MAC {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0}
|
||||
#if defined(__AVR__)
|
||||
#define wdt_en() wdt_enable(WDTO_8S)
|
||||
#define wdt_dis() wdt_disable()
|
||||
#define wdt_res() wdt_reset()
|
||||
#endif
|
||||
|
||||
#if defined(__ESP__)
|
||||
#define wdt_res()
|
||||
#define wdt_en()
|
||||
#define wdt_dis()
|
||||
#endif
|
||||
|
||||
#if defined(WATCH_DOG_TICKER_DISABLE) && defined(__AVR__)
|
||||
#define wdt_en() wdt_disable()
|
||||
#define wdt_dis() wdt_disable()
|
||||
#define wdt_res() wdt_disable()
|
||||
#endif
|
||||
|
||||
#include "Arduino.h"
|
||||
#include "DallasTemperature.h"
|
||||
#include <PubSubClient.h>
|
||||
#include <SPI.h>
|
||||
#include "utils.h"
|
||||
#include <string.h>
|
||||
#include <ModbusMaster.h>
|
||||
#include "aJSON.h"
|
||||
#include <Cmd.h>
|
||||
#include "stdarg.h"
|
||||
#include "item.h"
|
||||
#include "inputs.h"
|
||||
#include "Dhcp.h"
|
||||
|
||||
#if defined(__SAM3X8E__)
|
||||
|
||||
#include <DueFlashStorage.h>
|
||||
#include <watchdog.h>
|
||||
#include <ArduinoHttpClient.h>
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(__AVR__)
|
||||
#include "HTTPClient.h"
|
||||
#include <avr/pgmspace.h>
|
||||
#include <avr/wdt.h>
|
||||
#include <EEPROM.h>
|
||||
#endif
|
||||
|
||||
#if defined(__ESP__)
|
||||
#include <FS.h> //this needs to be first, or it all crashes and burns...
|
||||
#include "esp.h"
|
||||
#include <EEPROM.h>
|
||||
#include <ArduinoHttpClient.h>
|
||||
#endif
|
||||
|
||||
#ifdef _owire
|
||||
|
||||
#include "owTerm.h"
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(_dmxin) || defined(_dmxout) || defined (_artnet)
|
||||
|
||||
#include "dmx.h"
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef Wiz5500
|
||||
#include <Ethernet2.h>
|
||||
#else
|
||||
|
||||
#include <Ethernet.h>
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef _artnet
|
||||
#include <Artnet.h>
|
||||
#endif
|
||||
|
||||
#ifdef SD_CARD_INSERTED
|
||||
#include "sd_card_w5100.h"
|
||||
#endif
|
||||
|
||||
#ifdef _artnet
|
||||
extern Artnet *artnet;
|
||||
#endif
|
||||
|
||||
void watchdogSetup(void);
|
||||
void callback(char* topic, byte* payload, unsigned int length);
|
||||
|
||||
void mqttCallback(char *topic, byte *payload, unsigned int length);
|
||||
|
||||
#ifndef __ESP__
|
||||
|
||||
void printIPAddress();
|
||||
|
||||
#endif
|
||||
|
||||
void printMACAddress();
|
||||
|
||||
void restoreState();
|
||||
int lanLoop();
|
||||
void Changed (int i, DeviceAddress addr, int val);
|
||||
|
||||
int lanLoop();
|
||||
|
||||
void Changed(int i, DeviceAddress addr, int val);
|
||||
|
||||
void modbusIdle(void);
|
||||
void _handleHelp(int arg_cnt, char **args);
|
||||
void _kill(int arg_cnt, char **args);
|
||||
|
||||
void cmdFunctionHelp(int arg_cnt, char **args);
|
||||
|
||||
void cmdFunctionKill(int arg_cnt, char **args);
|
||||
|
||||
void applyConfig();
|
||||
void _loadConfig (int arg_cnt, char **args);
|
||||
|
||||
void cmdFunctionLoad(int arg_cnt, char **args);
|
||||
|
||||
int loadConfigFromEEPROM(int arg_cnt, char **args);
|
||||
void _mqttConfigRequest(int arg_cnt, char **args);
|
||||
|
||||
void cmdFunctionReq(int arg_cnt, char **args);
|
||||
|
||||
int mqttConfigRequest(int arg_cnt, char **args);
|
||||
int mqttConfigResp (char * as);
|
||||
void _saveConfigToEEPROM(int arg_cnt, char **args);
|
||||
void _setMacAddress(int arg_cnt, char **args);
|
||||
void _getConfig(int arg_cnt, char **args);
|
||||
void printBool (bool arg);
|
||||
void saveFlash(short n, char* str);
|
||||
void loadFlash(short n, char* str);
|
||||
int getConfig (int arg_cnt, char **args);
|
||||
|
||||
int mqttConfigResp(char *as);
|
||||
|
||||
void cmdFunctionSave(int arg_cnt, char **args);
|
||||
|
||||
void cmdFunctionSetMac(int arg_cnt, char **args);
|
||||
|
||||
void cmdFunctionGet(int arg_cnt, char **args);
|
||||
|
||||
void printBool(bool arg);
|
||||
|
||||
void saveFlash(short n, char *str);
|
||||
|
||||
void loadFlash(short n, char *str);
|
||||
|
||||
int getConfig(int arg_cnt, char **args);
|
||||
|
||||
void preTransmission();
|
||||
|
||||
void postTransmission();
|
||||
|
||||
void setup_main();
|
||||
|
||||
void loop_main();
|
||||
|
||||
void owIdle(void);
|
||||
|
||||
void modbusIdle(void);
|
||||
|
||||
void inputLoop(void);
|
||||
|
||||
void modbusLoop(void);
|
||||
|
||||
void thermoLoop(void);
|
||||
short thermoSetCurTemp(char * name, short t);
|
||||
|
||||
short thermoSetCurTemp(char *name, short t);
|
||||
|
||||
void modbusIdle(void);
|
||||
|
||||
void printConfigSummary();
|
||||
|
||||
void setupCmdArduino();
|
||||
|
||||
void setupMacAddress();
|
||||
|
||||
int getConfig(int arg_cnt, char **args);
|
||||
|
||||
void printFirmwareVersionAndBuildOptions();
|
||||
|
||||
#endif //LIGHTHUB_MAIN_H
|
||||
@@ -3,6 +3,33 @@
|
||||
#define PIO_SRC_REV v0.99
|
||||
#endif
|
||||
|
||||
#define TXEnablePin 13
|
||||
|
||||
#define T_ATTEMPTS 200
|
||||
#define IET_TEMP 0
|
||||
#define IET_ATTEMPTS 1
|
||||
|
||||
#define THERMO_GIST_CELSIUS 2
|
||||
|
||||
#define EEPROM_offset 32+6
|
||||
|
||||
#define INTERVAL_CHECK_INPUT 50
|
||||
#define INTERVAL_CHECK_MODBUS 2000
|
||||
#define THERMOSTAT_CHECK_PERIOD 5000
|
||||
|
||||
#ifndef MODBUS_SERIAL_BAUD
|
||||
#define MODBUS_SERIAL_BAUD 9600
|
||||
#endif
|
||||
|
||||
#ifndef SERIAL_BAUD
|
||||
#define SERIAL_BAUD 115200
|
||||
#endif
|
||||
|
||||
#ifndef CUSTOM_FIRMWARE_MAC
|
||||
#define DEFAULT_FIRMWARE_MAC {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0}
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef OUTTOPIC
|
||||
#define OUTTOPIC "/myhome/s_out/"
|
||||
#endif
|
||||
@@ -55,6 +82,3 @@
|
||||
#ifndef _dmxout
|
||||
#undef _artnet
|
||||
#endif
|
||||
|
||||
#define Q(x) #x
|
||||
#define QUOTE(x) Q(x)
|
||||
|
||||
@@ -17,8 +17,11 @@ GIT: https://github.com/anklimov/lighthub
|
||||
e-mail anklimov@gmail.com
|
||||
|
||||
*/
|
||||
#define Q(x) #x
|
||||
#define QUOTE(x) Q(x)
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
void PrintBytes(uint8_t* addr, uint8_t count, bool newline=0);
|
||||
void SetBytes(uint8_t* addr, uint8_t count, char * out);
|
||||
void SetAddr(char * out, uint8_t* addr);
|
||||
|
||||
@@ -10,8 +10,8 @@
|
||||
[platformio]
|
||||
src_dir = lighthub
|
||||
env_default =
|
||||
megaatmega2560
|
||||
; due
|
||||
; megaatmega2560
|
||||
due
|
||||
; esp8266
|
||||
|
||||
[env:due]
|
||||
|
||||
@@ -1,212 +0,0 @@
|
||||
//
|
||||
// Created by livello on 14.10.17.
|
||||
//
|
||||
|
||||
/*
|
||||
SD card test
|
||||
|
||||
This example shows how use the utility libraries on which the'
|
||||
SD library is based in order to get info about your SD card.
|
||||
Very useful for testing a card when you're not sure whether its working or not.
|
||||
|
||||
The circuit:
|
||||
* SD card attached to SPI bus as follows:
|
||||
** MOSI - pin 11 on Arduino Uno/Duemilanove/Diecimila
|
||||
** MISO - pin 12 on Arduino Uno/Duemilanove/Diecimila
|
||||
** CLK - pin 13 on Arduino Uno/Duemilanove/Diecimila
|
||||
** CS - depends on your SD card shield or module.
|
||||
Pin 4 used here for consistency with other Arduino examples
|
||||
|
||||
|
||||
created 28 Mar 2011
|
||||
by Limor Fried
|
||||
modified 9 Apr 2012
|
||||
by Tom Igoe
|
||||
*/
|
||||
|
||||
//template<class T> inline Print &operator <<(Print &obj, T arg) { obj.print(arg); return obj; }
|
||||
|
||||
|
||||
#include "sd_card_w5100.h"
|
||||
#include <SD.h>
|
||||
#include <SPI.h>
|
||||
//#include <iostream>
|
||||
|
||||
// set up variables using the SD utility library functions:
|
||||
Sd2Card card;
|
||||
SdVolume volume;
|
||||
SdFile sdFile;
|
||||
File myFile;
|
||||
|
||||
|
||||
char *entireFileContents;
|
||||
|
||||
// Arduino Ethernet shield: pin 4
|
||||
const int chipSelect = 4;
|
||||
|
||||
void bench() {
|
||||
/* uint8_t buf[BUF_SIZE];
|
||||
long maxLatency,minLatency,totalLatency,temp_DHT22;
|
||||
|
||||
|
||||
myFile = SD.open("test.txt", FILE_WRITE);
|
||||
|
||||
// if the file opened okay, write to it:
|
||||
if (myFile) {
|
||||
Serial.print("Writing to test.txt...");
|
||||
myFile.println("testing 1, 2, 3.");
|
||||
// close the file:
|
||||
|
||||
} else {
|
||||
// if the file didn'temp_DHT22 open, print an error:
|
||||
Serial.println("error opening test.txt");
|
||||
}
|
||||
|
||||
|
||||
for (uint16_t i = 0; i < (BUF_SIZE - 2); i++) {
|
||||
buf[i] = 'A' + (i % 26);
|
||||
}
|
||||
buf[BUF_SIZE - 2] = '\r';
|
||||
buf[BUF_SIZE - 1] = '\n';
|
||||
|
||||
Serial.println("File size MB: ");
|
||||
Serial.print(FILE_SIZE_MB);
|
||||
Serial.println("Buffer size ");
|
||||
Serial.print(BUF_SIZE);
|
||||
Serial.println("Starting write test, please wait.");
|
||||
|
||||
// do write test
|
||||
uint32_t n = FILE_SIZE / sizeof(buf);
|
||||
Serial.println("write speed and latency");
|
||||
Serial.print(" speed,max,min,avg");
|
||||
Serial.print(" KB/Sec,usec,usec,usec");
|
||||
for (uint8_t nTest = 0; nTest < WRITE_PASS_COUNT; nTest++) {
|
||||
// myFile.truncate(0);
|
||||
maxLatency = 0;
|
||||
minLatency = 9999999;
|
||||
totalLatency = 0;
|
||||
temp_DHT22 = millis();
|
||||
for (uint32_t i = 0; i < n; i++) {
|
||||
uint32_t m = micros();
|
||||
if (myFile.write(buf, sizeof(buf)) != sizeof(buf)) {
|
||||
Serial.println("write failed");
|
||||
}
|
||||
m = micros() - m;
|
||||
if (maxLatency < m) {
|
||||
maxLatency = m;
|
||||
}
|
||||
if (minLatency > m) {
|
||||
minLatency = m;
|
||||
}
|
||||
totalLatency += m;
|
||||
}
|
||||
myFile.flush();
|
||||
temp_DHT22 = millis() - temp_DHT22;
|
||||
int s = myFile.size();
|
||||
Serial.println(s / temp_DHT22);
|
||||
Serial.print(',');
|
||||
Serial.print(maxLatency);
|
||||
Serial.print(',');
|
||||
Serial.print(minLatency);
|
||||
Serial.print(',');
|
||||
Serial.print(totalLatency / n);
|
||||
}*/
|
||||
myFile.close();
|
||||
Serial.println("done.");
|
||||
}
|
||||
|
||||
char* sdW5100_readEntireFile(const char *filename) {
|
||||
SdFile requestedFile;
|
||||
if(requestedFile.open(sdFile,filename)) {
|
||||
Serial.println("Success open INDEX.HTM:");
|
||||
long time_started = millis();
|
||||
entireFileContents = new char[requestedFile.fileSize()];
|
||||
requestedFile.read(entireFileContents,requestedFile.fileSize());
|
||||
Serial.print(millis()-time_started);
|
||||
Serial.println(" milliseconds takes to read.");
|
||||
return entireFileContents;
|
||||
}
|
||||
else {
|
||||
Serial.print("Failed sdFile.open ");
|
||||
Serial.println(filename);
|
||||
|
||||
}
|
||||
return NULL;
|
||||
|
||||
}
|
||||
uint32_t sdW5100_getFileSize(const char *filename){
|
||||
SdFile requestedFile;
|
||||
if(requestedFile.open(sdFile,filename))
|
||||
return requestedFile.fileSize();
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
void sd_card_w5100_setup() {
|
||||
Serial.print("\nInitializing SD card...");
|
||||
// On the Ethernet Shield, CS is pin 4. It's set as an output by default.
|
||||
// Note that even if it's not used as the CS pin, the hardware SS pin
|
||||
// (10 on most Arduino boards, 53 on the Mega) must be left as an output
|
||||
// or the SD library functions will not work.
|
||||
pinMode(chipSelect, OUTPUT);
|
||||
|
||||
if (!card.init(SPI_FULL_SPEED, chipSelect)) {
|
||||
Serial.println("initialization failed. Things to check:");
|
||||
Serial.println("* is a card is inserted?");
|
||||
Serial.println("* Is your wiring correct?");
|
||||
Serial.println("* did you change the chipSelect pin to match your shield or module?");
|
||||
return;
|
||||
} else {
|
||||
Serial.println("Wiring is correct and a card is present.");
|
||||
}
|
||||
|
||||
// print the type of card
|
||||
Serial.print("\nCard 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("Unknown");
|
||||
}
|
||||
|
||||
// Now we will try to open the 'volume'/'partition' - it should be FAT16 or FAT32
|
||||
if (!volume.init(card)) {
|
||||
Serial.println("Could not find FAT16/FAT32 partition.\nMake sure you've formatted the card");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// print the type and size of the first FAT-type volume
|
||||
uint32_t volumesize;
|
||||
Serial.print("\nVolume type is FAT");
|
||||
Serial.println(volume.fatType(), DEC);
|
||||
Serial.println();
|
||||
|
||||
volumesize = volume.blocksPerCluster(); // clusters are collections of blocks
|
||||
volumesize *= volume.clusterCount(); // we'll have a lot of clusters
|
||||
volumesize *= 512; // SD card blocks are always 512 bytes
|
||||
Serial.print("Volume size (bytes): ");
|
||||
Serial.println(volumesize);
|
||||
Serial.print("Volume size (Kbytes): ");
|
||||
volumesize /= 1024;
|
||||
Serial.println(volumesize);
|
||||
Serial.print("Volume size (Mbytes): ");
|
||||
volumesize /= 1024;
|
||||
Serial.println(volumesize);
|
||||
|
||||
|
||||
Serial.println("\nFiles found on the card (name, date and size in bytes): ");
|
||||
sdFile.openRoot(volume);
|
||||
// list all files in the card with date and size
|
||||
sdFile.ls(LS_R | LS_DATE | LS_SIZE);
|
||||
Serial.println(sdW5100_readEntireFile("INDEX.HTM"));
|
||||
}
|
||||
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
//
|
||||
// Created by livello on 14.10.17.
|
||||
//
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifndef NODEMCU_STOPWATCH_SD_CARD_W5100_H
|
||||
#define NODEMCU_STOPWATCH_SD_CARD_W5100_H
|
||||
|
||||
#endif //NODEMCU_STOPWATCH_SD_CARD_W5100_H
|
||||
void sd_card_w5100_setup();
|
||||
void cidDmp();
|
||||
void bench();
|
||||
char* sdW5100_readEntireFile(const char *filename);
|
||||
uint32_t sdW5100_getFileSize(const char *filename);
|
||||
Reference in New Issue
Block a user