Connecting the PLCDuino to Cayenne


#1

About This Project

The PLCDuino is a pretty cool piece of kit for only $89! http://www.PLC.us. More deets here: http://www.digital-loggers.com/plchw.html

The challenge is that the support isn’t that great, and after pulling out bunches of hair, @wmontg5988 sent it to me. I was determined to connect it to Cayenne.

The PLCDuino is basically an Arduino Mega with a bunch of integrated shields and an ESP-02 attached, so it should be easy to get er done using a variation of this WifiShield with arduino uno compiling error.

For the above method to work, you need to make sure the ESP functions like a modem with the AT command set. By default, the ESP is programmed with NodeMCU. No problem, right? Devil is in the details.

The Details

The ESP is soldered to the board, and to program it, you need to analyze the schematic and see how it is connected. The ESP is connected to Serial2 in Arduino-speak. Then we need to know how the control signals are mapped. See schematic. https://www.digital-loggers.com/plcschematics.pdf

Fortunately I found a library, and an esp_flash_helper sketch.

Running the sketch, it is evident that there is a “feature” where the serial DTR line is used to reset the PLC when the baud rate changes. However, when we change baud rate to flash the ESP, the PLC resets, as do our connections to the ESP :frowning:

I was able to program it by connecting to the ESP programming header at J9 with a USB to Serial dongle, but not everyone has one of those, and I don’t like driving into an output line in the case of two TX lines talking to one RX line.
At that time, I determined that the programming baud rate was also wrong.

Analyzing the schematic, I determined that I could force the Mega reset line high so the helper program would work, and the fruits of my labour are yours.

The Nitty Gritty Details

Give yourself some time. This is going to be a ride.

DANGER WILL ROBINSON! You are about to void your warranty. You are about to touch hardware. Make sure you take ESD precautions. Make sure when powering up the PLC, you check polarities. Make sure you don’t have the PLC powered up when you are attaching the jumper. When the jumper is attached, do not press the reset button. Yadda. Yadda. Yadda. This is completely at your own risk. Have a nice day :slight_smile:

  1. Install the support libraries from here: https://github.com/digitalloggers/PLDuino/tree/master/Arduino/libraries.

  2. You will also need the Cayenne bits from here: WifiShield with arduino uno compiling error

  3. Open your PLC by lifting the body away from the tabs on the USB side.

  4. Carefully lift the top and remove the twist tie around the speaker wire for extra reach.

  5. Now find J7 to the left of the Touchscreen connector on the main board, and attach a jumper between pins 2 and 5. This will allow us to change the baud rate for programming without the PLC resetting!!!

  6. Load this sketch and download my simplified helper sketch to the PLC.

#PLCDuino_ESPFlashHelper Sketch

#include <PLDuino.h>
#include <PLDTouch.h>
#include <PLDuinoGUI.h>
#include <using_namespace_PLDuinoGUI.h>
#include <TMRpcm_PLDuino.h>
#include <SPI.h>
#include <SD.h>
#include <Adafruit_GFX.h>
#include <Adafruit_ILI9341.h>
#include <DS3232RTC.h>
#include <TimeLib.h>
#include <Wire.h>
#include <avr/io.h>

Adafruit_ILI9341 tft = Adafruit_ILI9341(PLDuino::LCD_CS, PLDuino::LCD_DC);
PLDTouch touch(PLDuino::TOUCH_CS, PLDuino::TOUCH_IRQ);


void resetESP()
{
  digitalWrite(PLDuino::ESP_RST, LOW);
  delay(1000);
  digitalWrite(PLDuino::ESP_RST, HIGH);
}

void setupFlashMode()
{
  digitalWrite(PLDuino::ESP_GPIO0, LOW);
  resetESP();

  Serial.begin(74880);
  Serial2.begin(74880);

  Button btnReset("RESET ESP", ILI9341_RED, ILI9341_MAROON);
  btnReset.setPositionAndSize(100, 100, 130, 40);
  btnReset.draw(tft);

  Label lblNote("Ready to Flash ESP-02 at  74880 baud.", ILI9341_WHITE, ILI9341_BLACK, HORZ_LEFT|VERT_TOP);
  lblNote.setPositionAndSize(10, 25, 300, 120);
  lblNote.draw(tft);

  while(true)
  {
    if (touch.dataAvailable())
    {
      Point pt = touch.read();
      int x = pt.x;
      int y = pt.y;
      
      if (btnReset.isTouched(x, y))
      {
        resetESP();
      }

    }  
      
    if (Serial2.available()) Serial.write(Serial2.read());
    if (Serial.available()) Serial2.write(Serial.read());
  }
}

void setup()
{
  PLDuino::init();
  PLDuino::enableLCD();
  PLDuino::enableESP();
  tft.begin();
  tft.setRotation(3);
  touch.init(1);
  setupFlashMode();

  while(1);
}

void loop() {}

.
7. Load 'er up, and we are ready to flash. Time for some 80s dancing…
8. Clone the NodeMCU Flasher application, or whatever you like. Node flasher is here: https://github.com/nodemcu/nodemcu-flasher
9. Run the exe in the release directory for your OS, 32 or 64 bit.
10. Get the AT firmware. I used this one: http://www.electrodragon.com/w/File:V1.3.0.2_AT_Firmware.bin.zip
11. Now configure based on the pictures, and make sure you use the Arduino serial port (serial monitor closed).

.
12. Now press Flash. The flasher should find the ESP addresses, and the progress bar should slowly start to climb.
13. When done, the bottom left will show ‘Ready’.
14. You just flashed the ESP. Squeee! NOW STOP!
15. Remove power from your PLCDuino and remove that jumper you placed on J7!!!
16. Close up the box and power it back on.
17. You can now drop in your Cayenne sketch.
18. Here you go:

#PLCDuino_Cayenne_Connect

/*
Cayenne ESP8266 Shield WiFi Example
Adapted from Blynk's ESP8266_Shield_HardSer Example

This sketch connects to the Cayenne server using an ESP8266 WiFi module as a shield connected
via a hardware serial to an Arduino.

You should install the ESP8266HardwareSerial.zip library via the Arduino IDE (Sketch->Include Library->Add .ZIP Library)
from the Cayenne extras/libraries folder (e.g. My Documents\Arduino\libraries\Cayenne\extras\libraries) to compile this example.

NOTE: Ensure a stable serial connection to ESP8266!
      Firmware version 1.0.0 (AT v0.22) or later is needed.
      You can change ESP baud rate. Connect to AT console and call:
          AT+UART_DEF=115200,8,1,0,0

For Cayenne Dashboard widgets using digital or analog pins this sketch will automatically
send data on those pins to the Cayenne server. If the widgets use Virtual Channels, data
should be sent to those channels using virtualWrites. Examples for sending and receiving
Virtual Channel data are under the Basics folder.
*/

//#define CAYENNE_DEBUG         // Uncomment to show debug messages
#define CAYENNE_PRINT Serial  // Comment this out to disable prints and save space
#include <CayenneESP8266Shield.h>
#include <PLDuino.h>
#include <PLDuinoGUI.h>
#include <TMRpcm_PLDuino.h>
#include <SPI.h>
#include <SD.h>
#include <Adafruit_GFX.h>
#include <Adafruit_ILI9341.h>
#include <PLDuino.h>
#include <PLDTouch.h>
#include <PLDuinoGUI.h>
#include <using_namespace_PLDuinoGUI.h>
#include <DS3232RTC.h>
#include <TimeLib.h>
#include <Wire.h>
#include <avr/io.h>

Adafruit_ILI9341 tft = Adafruit_ILI9341(PLDuino::LCD_CS, PLDuino::LCD_DC);
PLDTouch touch(PLDuino::TOUCH_CS, PLDuino::TOUCH_IRQ);

// Cayenne authentication token. This should be obtained from the Cayenne Dashboard.
char token[] = "...";
// Your network name and password.
char ssid[] = "...";
char password[] = "...";

// Set ESP8266 Serial object
 #define EspSerial Serial2
ESP8266 wifi(EspSerial);

void setup()
{
  PLDuino::init();
  PLDuino::enableLCD();
  PLDuino::enableESP();
  tft.begin();
  tft.setRotation(3);
  touch.init(1);

  Serial.begin(9600);
  delay(100);
  // Set ESP8266 baud rate
  EspSerial.begin(115200);
  delay(100);

  Cayenne.begin(token, wifi, ssid, password);

 // while(touch.dataAvailable()) touch.read();
 // while(!touch.dataAvailable()); touch.read();
 // tft.fillScreen(ILI9341_BLACK);

}

void loop()
{
  Cayenne.run();
}

.
19. Fill in your credentials and your Arduino Cayenne Token, and upload to the PLCDuino.
20. Note, if it doesn’t compile, you probably need to look above and grab the files in the linked forum post.
21. If all’s well, your dashboard should pop up, and you can start adding some stuff to your dashboard.
22. As a start, channels 2-7 are the relay outputs.

What’s Connected

Check out these features:

  • ATMega2560 based
  • WiFi with external long range antenna.
  • 2.4" Color LCD touch screen and speaker.
  • Six fused DPST power relays.
  • Eight protected digital outputs with 500mA open collector drivers
  • Eight protected & isolated digital inputs 3-24V AC/DC
  • Eight 10-bit ADC inputs.
  • Clock calendar & battery for scheduling.
  • RS-232 for long distance wired comm.
  • Expanded 128Mb & 4GB FLASH.
  • DIN rail or panel mount.
  • 12-28 VDC powered.
  • Full Arduino compatibility.

Triggers & Alerts

With all this IO. WHOOOSH! Mind blown.

Scheduling

Soon. Soon.

Photos of the Project

Cheers,

Craig


Offline Trouble
#2

It is very cool! Thank you!


#3

Two awesome projects in one weekend…I need to step up my game


#4

@ognqn.chikov and @adam,

Grab one up. This thing has enough horsepower to run a small homebrewery, a hydroponic garden, or even a dart playing robot.

Who doesn’t want a dart throwing robot?!

Cheers,

Craig


#5

I need to order another so I can play. My first one is sitting in the Philippines.
Thanks!


#6

I will order too :slight_smile: I want to implement everything in one device. :slight_smile:


#7

@kreggly

Well, Well, Well: looky who finally made his own PLCduino work. I am online and have all 6 relays working. Funny how no code is involved for a relay widget. You definitely earned the PLCduino that I shipped you!!!

On another note, the resistor packs for the analog inputs are 100k and I figured thru non-mathematician methods that 1 meg packs would give me a range of 0-60 volts, 5 volts added per added 100k. Am I wrong?

Thanks,

William


#8

Hey @kreggly

could you look at this sketch and tell me what I am missing? My readings are way off on the dashboard. The voltage code works fine on a regular Mega.

thanks


#9

Hi @wmontg5988,

Woot Woot. Congrats on getting it online.

A 1Meg series resistor will give you 0-55V input, with 5V at the ADC equal to 55V at the input.

HOWEVER, if you look at page 275 of the Mega microcontroller specification:

http://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-2549-8-bit-AVR-Microcontroller-ATmega640-1280-1281-2560-2561_datasheet.pdf

The ADC is only designed for around a 10K input impedance, so if you are going into the stratosphere, you really need to slow down your sample time. You can help this along by adding some 100nF caps at the ADC input, but that is going to require some soldering. I recommend removing RN2 and soldering caps across it, then dropping it back in.

To set the sampling prescaler, you need to set the ADPS bits in the ADCSRA register. See page 285.

Cheers,

Craig


#10

@wmontg5988,

I would simplify your code a bit:

//10V is fullscale, 1024 is the resolution
#define ADC_SCALE 10/1024

int analogValue0 = analogRead(A0);
voltage0 = analogValue0 * ADC_SCALE;

You can also use the Arduino map function:

int analogValue0 = analogRead(A0);
voltage0 = map(analogValue0, 0, 1023, 0, 10000); //gives you an integer output in mV

Cheers,

Craig


#11

Um, Chinese? Yes? There was a whooshing sound over my head haha. I will try the caps, maybe on the backside. Setting registers etc is a bit beyond my tech right now. I really don’t need 60 volt limits, just thought that would be a safe limit since some of the solar panel power could exceed 40v and battery 33v. I will try your code example too. Also, have you seen an i2c connection in the schematics? I read that the rtc uses it.

William


#12

You could first try taking samples over 100ms or so then average them.


#13

Also, I wouldn’t worry too much about damage as a 1M resistor is limiting
the current and there are 5.6V zeners protecting the inputs from
overvoltage, even if you did put 60V in.

Cheers,

Craig


#14

@wmontg5988,

I tested it this way…

CAYENNE_OUT(V1)
{
int adcVal = analogRead(A0);
float adcVoltage = 10.0*adcVal/1024;
Cayenne.virtualWrite(V1,adcVoltage);
btnVoltage.setText(String(adcVoltage));
btnVoltage.draw(tft);
}


#15

@kreggly

I’m getting btnvoltage was not declared in this scope. I commented that part out assuming it was to print to lcd screen. me thinks I need a little more info maybe? either way i’m still getting weird voltage readings (4665.00 volts A0) and the other 2 gages not in the code are reading volts too. Maybe I need to wait for some caps for that problem.

William


#16

Yeah, I used that to display the value on the LCD.

I can throw you the full sketchie of you wants.


#17

That would be great. It will enforce the learning process. Seems I learn more by example.

:grin:


#19

@wmontg5988,

Here is my sketch. Voltage input up to 10V on Anolog In 0.

Cheers,

Craig

/*
Cayenne ESP8266 Shield WiFi Example
Adapted from Blynk's ESP8266_Shield_HardSer Example

This sketch connects to the Cayenne server using an ESP8266 WiFi module as a shield connected
via a hardware serial to an Arduino.

You should install the ESP8266HardwareSerial.zip library via the Arduino IDE (Sketch->Include Library->Add .ZIP Library)
from the Cayenne extras/libraries folder (e.g. My Documents\Arduino\libraries\Cayenne\extras\libraries) to compile this example.

NOTE: Ensure a stable serial connection to ESP8266!
      Firmware version 1.0.0 (AT v0.22) or later is needed.
      You can change ESP baud rate. Connect to AT console and call:
          AT+UART_DEF=115200,8,1,0,0

For Cayenne Dashboard widgets using digital or analog pins this sketch will automatically
send data on those pins to the Cayenne server. If the widgets use Virtual Channels, data
should be sent to those channels using virtualWrites. Examples for sending and receiving
Virtual Channel data are under the Basics folder.
*/



//#define CAYENNE_DEBUG         // Uncomment to show debug messages
#define CAYENNE_PRINT Serial  // Comment this out to disable prints and save space
#include <CayenneESP8266Shield.h>
#include <PLDuino.h>
#include <PLDuinoGUI.h>
#include <TMRpcm_PLDuino.h>
#include <SPI.h>
#include <SD.h>
#include <Adafruit_GFX.h>
#include <Adafruit_ILI9341.h>
#include <PLDuino.h>
#include <PLDTouch.h>
#include <PLDuinoGUI.h>
#include <using_namespace_PLDuinoGUI.h>
#include <DS3232RTC.h>
#include <TimeLib.h>
#include <Wire.h>
#include <avr/io.h>


Adafruit_ILI9341 tft = Adafruit_ILI9341(PLDuino::LCD_CS, PLDuino::LCD_DC);
PLDTouch touch(PLDuino::TOUCH_CS, PLDuino::TOUCH_IRQ);

Button btnVoltage("Volts", ILI9341_YELLOW, ILI9341_BLACK);

// Cayenne authentication token. This should be obtained from the Cayenne Dashboard.
char token[] = "";
// Your network name and password.
char ssid[] = "";
char password[] = "";

// Set ESP8266 Serial object
 #define EspSerial Serial2
ESP8266 wifi(EspSerial);

void setup()
{
  PLDuino::init();
  PLDuino::enableLCD();
  PLDuino::enableESP();
  tft.begin();
  tft.setRotation(3);
  touch. init(1);

  Serial.begin(9600);
  delay(100);
  // Set ESP8266 baud rate
  EspSerial.begin(115200);
  delay(100);

  Cayenne.begin(token, wifi, ssid, password);

  btnVoltage.setPositionAndSize(60, 70, 200, 100);
  btnVoltage.draw(tft);
  
 
}

void loop()
{
  Cayenne.run();
}

CAYENNE_OUT(V1)
{
  int adcVal = analogRead(A0);
  float adcVoltage = 10.0*adcVal/1024;
  Cayenne.virtualWrite(V1,adcVoltage);
  btnVoltage.setText(String(adcVoltage));
  btnVoltage.draw(tft);
}

#20

If I’m using 1 meg resistor packs for 0-55v would I multiply by 55? Reading won’t pass 10v even with 17v going in. Are the zener diodes before or after the divider array?


#21

Test that it works with the original packs first with a lower voltage.

I dont have those r packs so cant verify myself.