Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Switch more GPIOs. Add initial readme #2

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 45 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# ArduinoEasy = Arduino Mega 2560 + Ethernet Shield

This is experimental project that may not be ready for production usage. This project is based on ESPEasy code backported to Arduino.

Please visit [discussion forum](https://www.letscontrolit.com/forum/viewtopic.php?f=18&t=2234) if you have questions and need help.
Binary image to try ArduinoEasy is available on [wiki page](https://www.letscontrolit.com/wiki/index.php/ArduinoEasy)

## Building
The latest sources can be build using Arduino 1.8.5 with recent libraries. Arduino will ask to rename src folder to ArduinoEasy once you open ArduinoEasy.ino file.
Make sure to add base64 library. Open Sketch -> Include library -> Add .ZIP library -> select folder /lib/Base64
Other libraries that should be also available
- Wire at version 1.0
- SPI at version 1.0
- SD at version 1.2.2
- Ethernet at version 1.1.2
- PubSubClient at version 2.6
- ArduinoJson at version 5.13.1

## Usage
MicroSD card is used to store configuration. Make sure to format microSD or microSDHC card to FAT and insert it into Arduino. Otherwise you will get following error in console.

PID:0
Version:0
INIT : Incorrect PID or version!

## Mega Switch setup
Arduino Mega has lots of GPIOs and it is possible to control most of them using ArduinoEasy.
List of GPIOs that can be controlled: 3, 5 - 9, 14 - 49, 56 - 69.
56-69 pins are used for A2-A15 pins. A0 and A1 are required to work with SD card.

### MQTT control
To control GPIO via MQTT send "1" or "0" to corresponding pin number. Here is example of topic to control pin 39 on device named ArduinoEasyRocks.

/ArduinoEasyRocks/gpio/39

### OpenHab configuration
Items configuration with switch defined

Switch StairsUpHall <light> {mqtt=">[oh2mqtt:/ArduinoEasyRocks/gpio/39:command:ON:1],>[oh2mqtt:/ArduinoEasyRocks/gpio/39:command:OFF:0]"}

Sitemap with corresponding switch to show it on basic UI

Switch item=StairsUpHall label="Upstairs hall"

Make sure to properly configure MQTT binding.
5 changes: 4 additions & 1 deletion src/ArduinoEasy.ino
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,7 @@ EthernetServer MyWebServer(80);
#if FEATURE_MQTT
EthernetClient mqtt;
PubSubClient MQTTclient(mqtt);
long lastMQTTReconnectAttempt = 0;
#endif

#define EthernetShield_CS_SDCard 4
Expand Down Expand Up @@ -831,7 +832,9 @@ void backgroundtasks()
{
WebServerHandleClient();
#if FEATURE_MQTT
MQTTclient.loop();
if(!MQTTclient.loop()) {
MQTTCheck(); // MQTT client is no longer connected. Attempt to reconnect
}
#endif
statusLED(false);
checkUDP();
Expand Down
64 changes: 30 additions & 34 deletions src/Controller.ino
Original file line number Diff line number Diff line change
Expand Up @@ -104,36 +104,30 @@ void MQTTConnect()
LWTTopic.replace(F("/#"), F("/status"));
LWTTopic.replace(F("%sysname%"), Settings.Name);

for (byte x = 1; x < 3; x++)
{
String log = "";
boolean MQTTresult = false;
String log = "";
boolean MQTTresult = false;

String msg = F("Connection Lost");
if ((SecuritySettings.ControllerUser[0] != 0) && (SecuritySettings.ControllerPassword[0] != 0))
MQTTresult = MQTTclient.connect(clientid.c_str(), SecuritySettings.ControllerUser, SecuritySettings.ControllerPassword, LWTTopic.c_str(), 0, 0, msg.c_str());
else
MQTTresult = MQTTclient.connect(clientid.c_str(), LWTTopic.c_str(), 0, 0, msg.c_str());
String msg = F("Connection Lost");
if ((SecuritySettings.ControllerUser[0] != 0) && (SecuritySettings.ControllerPassword[0] != 0))
MQTTresult = MQTTclient.connect(clientid.c_str(), SecuritySettings.ControllerUser, SecuritySettings.ControllerPassword, LWTTopic.c_str(), 0, 0, msg.c_str());
else
MQTTresult = MQTTclient.connect(clientid.c_str(), LWTTopic.c_str(), 0, 0, msg.c_str());

if (MQTTresult)
{
log = F("MQTT : Connected to broker");
addLog(LOG_LEVEL_INFO, log);
subscribeTo = Settings.MQTTsubscribe;
subscribeTo.replace(F("%sysname%"), Settings.Name);
MQTTclient.subscribe(subscribeTo.c_str());
log = F("Subscribed to: ");
log += subscribeTo;
addLog(LOG_LEVEL_INFO, log);
break; // end loop if succesfull
}
else
{
log = F("MQTT : Failed to connected to broker");
addLog(LOG_LEVEL_ERROR, log);
}

delay(500);
if (MQTTresult)
{
log = F("MQTT : Connected to broker");
addLog(LOG_LEVEL_INFO, log);
subscribeTo = Settings.MQTTsubscribe;
subscribeTo.replace(F("%sysname%"), Settings.Name);
MQTTclient.subscribe(subscribeTo.c_str());
log = F("Subscribed to: ");
log += subscribeTo;
addLog(LOG_LEVEL_INFO, log);
}
else
{
log = F("MQTT : Failed to connected to broker");
addLog(LOG_LEVEL_ERROR, log);
}
}

Expand All @@ -147,12 +141,14 @@ void MQTTCheck()
if (Protocol[ProtocolIndex].usesMQTT)
if (!MQTTclient.connected())
{
String log = F("MQTT : Connection lost");
addLog(LOG_LEVEL_ERROR, log);
connectionFailures += 2;
MQTTclient.disconnect();
delay(1000);
MQTTConnect();
if (millis() - lastMQTTReconnectAttempt > 60000) {
// Reconnect attempts once per minute
String log = F("MQTT : Connection lost");
addLog(LOG_LEVEL_ERROR, log);
connectionFailures++;
MQTTConnect();
lastMQTTReconnectAttempt = millis();
}
}
else if (connectionFailures)
connectionFailures--;
Expand Down
18 changes: 11 additions & 7 deletions src/Misc.ino
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ void SelectSDCard(boolean sd)
digitalWrite(EthernetShield_CS_W5100, sd);
digitalWrite(EthernetShield_CS_SDCard, !sd);
}

/*********************************************************************************************\
Get value count from sensor type
\*********************************************************************************************/
Expand Down Expand Up @@ -413,7 +413,7 @@ void fileSystemCheck()
pinMode(EthernetShield_CS_SDCard, OUTPUT);
pinMode(EthernetShield_CS_W5100, OUTPUT);
SelectSDCard(true);

if (SD.begin(EthernetShield_CS_SDCard))
{
String log = F("SD Mount successful");
Expand Down Expand Up @@ -659,7 +659,7 @@ void LoadCustomControllerSettings(byte* memAddress, int datasize)
\*********************************************************************************************/
void SaveToFile(const __FlashStringHelper* fname, int index, byte* memAddress, int datasize)
{
File f = SD.open(fname, FILE_WRITE);
File f = SD.open(fname, O_READ | O_WRITE);
if (f)
{
f.seek(index);
Expand All @@ -670,7 +670,12 @@ void SaveToFile(const __FlashStringHelper* fname, int index, byte* memAddress, i
pointerToByteToSave++;
}
f.close();
String log = F("FILE : File saved");
String log = F("FILE : File saved ");
log += fname;
log += F(" index ");
log += index;
log += F(" size ");
log += datasize;
addLog(LOG_LEVEL_INFO, log);
}
}
Expand Down Expand Up @@ -861,7 +866,7 @@ void addLog(byte loglevel, const char *line)
}
logFile.close();
}

}


Expand Down Expand Up @@ -1521,7 +1526,7 @@ unsigned long getNtpTime()
{
const char* ntpServerName = "pool.ntp.org";
unsigned long result=0;

IPAddress timeServerIP;

// The W5100 seems to have an issue with mixing TCP UDP on the same socket.
Expand Down Expand Up @@ -2004,4 +2009,3 @@ void createRuleEvents(byte TaskIndex)
rulesProcessing(eventString);
}
}

20 changes: 12 additions & 8 deletions src/_P001_Switch.ino
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ boolean Plugin_001(byte function, struct EventStruct *event, String& string)

switchstate[event->TaskIndex] = digitalRead(Settings.TaskDevicePin1[event->TaskIndex]);
outputstate[event->TaskIndex] = switchstate[event->TaskIndex];

// if boot state must be send, inverse default state
if (Settings.TaskDevicePluginConfig[event->TaskIndex][3])
{
Expand Down Expand Up @@ -218,7 +218,7 @@ boolean Plugin_001(byte function, struct EventStruct *event, String& string)
if (command == F("gpio"))
{
success = true;
if (event->Par1 >= 2 && event->Par1 <= 13)
if (Plugin_001_updatable_pin(event->Par1))
{
pinMode(event->Par1, OUTPUT);
digitalWrite(event->Par1, event->Par2);
Expand All @@ -232,14 +232,14 @@ boolean Plugin_001(byte function, struct EventStruct *event, String& string)
if (command == F("pwm"))
{
success = true;
if (event->Par1 >= 2 && event->Par1 <= 13)
if (Plugin_001_updatable_pin(event->Par1))
{
pinMode(event->Par1, OUTPUT);

if(event->Par3 != 0)
{
byte prev_mode;
uint16_t prev_value;
uint16_t prev_value;
getPinState(PLUGIN_ID_001, event->Par1, &prev_mode, &prev_value);
if(prev_mode != PIN_MODE_PWM)
prev_value = 0;
Expand All @@ -255,7 +255,7 @@ boolean Plugin_001(byte function, struct EventStruct *event, String& string)
delay(1);
}
}

analogWrite(event->Par1, event->Par2);
setPinState(PLUGIN_ID_001, event->Par1, PIN_MODE_PWM, event->Par2);
log = String(F("SW : GPIO ")) + String(event->Par1) + String(F(" Set PWM to ")) + String(event->Par2);
Expand All @@ -267,7 +267,7 @@ boolean Plugin_001(byte function, struct EventStruct *event, String& string)
if (command == F("pulse"))
{
success = true;
if (event->Par1 >= 2 && event->Par1 <= 13)
if (Plugin_001_updatable_pin(event->Par1))
{
pinMode(event->Par1, OUTPUT);
digitalWrite(event->Par1, event->Par2);
Expand All @@ -283,7 +283,7 @@ boolean Plugin_001(byte function, struct EventStruct *event, String& string)
if (command == F("longpulse"))
{
success = true;
if (event->Par1 >= 2 && event->Par1 <= 13)
if (Plugin_001_updatable_pin(event->Par1))
{
pinMode(event->Par1, OUTPUT);
digitalWrite(event->Par1, event->Par2);
Expand Down Expand Up @@ -344,3 +344,7 @@ boolean Plugin_001(byte function, struct EventStruct *event, String& string)
}
return success;
}

boolean Plugin_001_updatable_pin(int pin) {
return pin == 3 || ( pin >= 5 && pin <= 9) || ( pin >= 14 && pin <= 49) || ( pin >= 56 && pin <= 69);
}