Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
NodeMCU control PLC through Wifi network
/*----------------------------------------------------------------------
Thank to Davide Nardella
----------------------------------------------------------------------*/
// Wifi -> #define S7WIFI
// Cable -> #define S7WIRED
#define S7WIFI
#include <SPI.h>
#include <Ethernet.h>
#ifdef S7WIFI
#include <ESP8266WiFi.h>
#endif
#include "Settimino.h"
#include <Wire.h>
// MPU6050 Slave Device Address
const uint8_t MPU6050SlaveAddress = 0x68;
// Select SDA and SCL pins for I2C communication
const uint8_t scl = D1;
const uint8_t sda = D2;
// sensitivity scale factor respective to full scale setting provided in datasheet
const uint16_t AccelScaleFactor = 16384;
const uint16_t GyroScaleFactor = 131;
// MPU6050 few configuration register addresses
const uint8_t MPU6050_REGISTER_SMPLRT_DIV = 0x19;
const uint8_t MPU6050_REGISTER_USER_CTRL = 0x6A;
const uint8_t MPU6050_REGISTER_PWR_MGMT_1 = 0x6B;
const uint8_t MPU6050_REGISTER_PWR_MGMT_2 = 0x6C;
const uint8_t MPU6050_REGISTER_CONFIG = 0x1A;
const uint8_t MPU6050_REGISTER_GYRO_CONFIG = 0x1B;
const uint8_t MPU6050_REGISTER_ACCEL_CONFIG = 0x1C;
const uint8_t MPU6050_REGISTER_FIFO_EN = 0x23;
const uint8_t MPU6050_REGISTER_INT_ENABLE = 0x38;
const uint8_t MPU6050_REGISTER_ACCEL_XOUT_H = 0x3B;
const uint8_t MPU6050_REGISTER_SIGNAL_PATH_RESET = 0x68;
int16_t AccelX, AccelY, AccelZ, Temperature, GyroX, GyroY, GyroZ;
#define DO_IT_SMALL
// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
byte mac[] = {
0x90, 0xA2, 0xDA, 0x0F, 0x08, 0xE11 };
IPAddress Local(192,168,0,70); // Local Address
IPAddress PLC(192,168,0,71); // PLC Address
// Following constants are needed if you are connecting via WIFI
// The ssid is the name of my WIFI network (the password obviously is wrong)
char ssid[] = "FPT-Telecom"; // Your network SSID (name)
char pass[] = "12345689"; // Your network password (if any)
IPAddress Gateway(192, 168, 0, 1);
IPAddress Subnet(255, 255, 255, 0);
int DBNum = 2; // This DB must be present in your PLC
byte Buffer[512];
#ifdef S7WIFI
// S7Client will create a WiFiClient as TCP Client
S7Client Client(_S7WIFI);
#else
// S7Client will create an EthernetClient as TCP Client
S7Client Client(_S7WIRED);
#endif
unsigned long Elapsed; // To calc the execution time
//----------------------------------------------------------------------
// Setup : Init Ethernet and Serial port
//----------------------------------------------------------------------
void setup() {
// Open serial communications and wait for port to open:
Wire.begin(sda, scl);
MPU6050_Init();
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for Leonardo only
}
#ifdef S7WIFI
//--------------------------------------------- ESP8266 Initialization
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, pass);
WiFi.config(Local, Gateway, Subnet);
while (WiFi.status() != WL_CONNECTED)
{
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
Serial.print("Local IP address : ");
Serial.println(WiFi.localIP());
#else
//--------------------------------Wired Ethernet Shield Initialization
// Start the Ethernet Library
Ethernet.begin(mac, Local);
// Setup Time, someone said me to leave 2000 because some
// rubbish compatible boards are a bit deaf.
delay(2000);
Serial.println("");
Serial.println("Cable connected");
Serial.print("Local IP address : ");
Serial.println(Ethernet.localIP());
#endif
}
//----------------------------------------------------------------------
// Connects to the PLC
//----------------------------------------------------------------------
bool Connect()
{
int Result=Client.ConnectTo(PLC,
0, // Rack (see the doc.)
2); // Slot (see the doc.)
Serial.print("Connecting to ");Serial.println(PLC);
if (Result==0)
{
Serial.print("Connected ! PDU Length = ");Serial.println(Client.GetPDULength());
}
else
Serial.println("Connection error");
return Result==0;
}
//----------------------------------------------------------------------
// Dumps a buffer (a very rough routine)
//----------------------------------------------------------------------
void Dump(void *Buffer, int Length)
{
int i, cnt=0;
pbyte buf;
if (Buffer!=NULL)
buf = pbyte(Buffer);
else
buf = pbyte(&PDU.DATA[0]);
Serial.print("[ Dumping ");Serial.print(Length);
Serial.println(" bytes ]==========================");
for (i=0; i<Length; i++)
{
cnt++;
if (buf[i]<0x10)
Serial.print("0");
Serial.print(buf[i], HEX);
Serial.print(" ");
if (cnt==16)
{
cnt=0;
Serial.println();
}
}
Serial.println("===============================================");
}
//----------------------------------------------------------------------
// Prints the Error number
//----------------------------------------------------------------------
void CheckError(int ErrNo)
{
Serial.print("Error No. 0x");
Serial.println(ErrNo, HEX);
// Checks if it's a Severe Error => we need to disconnect
if (ErrNo & 0x00FF)
{
Serial.println("SEVERE ERROR, disconnecting.");
Client.Disconnect();
}
}
//----------------------------------------------------------------------
// Profiling routines
//----------------------------------------------------------------------
void MarkTime()
{
Elapsed=millis();
}
//----------------------------------------------------------------------
void ShowTime()
{
// Calcs the time
Elapsed=millis()-Elapsed;
Serial.print("Job time (ms) : ");
Serial.println(Elapsed);
}
//----------------------------------------------------------------------
// Main Loop
//----------------------------------------------------------------------
void loop()
{
int Size, Result;
void *Target;
double Ax, Ay, Az, T, Gx, Gy, Gz;
double roll = 0.00, pitch = 0.00; //Roll & Pitch are the angles which rotate by the axis X and y
Read_RawValue(MPU6050SlaveAddress, MPU6050_REGISTER_ACCEL_XOUT_H);
//divide each with their sensitivity scale factor
Ax = (double)AccelX/AccelScaleFactor;
Ay = (double)AccelY/AccelScaleFactor;
Az = (double)AccelZ/AccelScaleFactor;
T = (double)Temperature/340+36.53; //temperature formula
Gx = (double)GyroX/GyroScaleFactor;
Gy = (double)GyroY/GyroScaleFactor;
Gz = (double)GyroZ/GyroScaleFactor;
roll = atan2(Ay , Az) * 57.3;
pitch = atan2((- Ax) , sqrt(Ay * Ay + Az * Az)) * 57.3;
//Serial.print(" Roll: "); Serial.println(roll);
//Serial.print(" Pitch: "); Serial.println(pitch);
//Serial.print(" Az: "); Serial.print(Az);
//Serial.print(" T: "); Serial.print(T);
//Serial.print(" Gx: "); Serial.print(Gx);
//Serial.print(" Gy: "); Serial.print(Gy);
//Serial.print(" Gz: "); Serial.println(Gz);
delay(100);
//----------------------------------------------------------------------
// Programm_for as to variable Int
//----------------------------------------------------------------------
int write_data = (int)(map(roll, -180, 180, -1000, 1000)); //// Write roll to PLC
//Serial.print(" Write data prepare: ");Serial.println(write_data);
//delay(500);
//----------------------------------------------------------------------
// Start connessione DB
//----------------------------------------------------------------------
#ifdef DO_IT_SMALL
Size=2;
Target = NULL; // Uses the internal Buffer (PDU.DATA[])
#else
Size=1024;
Target = &Buffer; // Uses a larger buffer
#endif
// Connection
while (!Client.Connected)
{
if (!Connect())
delay(500);
}
//----------------------------------------------------------------------
// Little_Endian & Big_Endian convertion
//----------------------------------------------------------------------
int write_data_var1 = write_data;
byte* bytes = (byte*)& write_data_var1;
//----------------------------------------------------------------------
// Word/Int Correction
//----------------------------------------------------------------------
void Correction(void *bytes);
{
byte *pointerbyte;
byte temp;
pointerbyte=(byte*)(bytes);
// Swap byte
temp=*(pointerbyte+1);
*(pointerbyte+1) = *pointerbyte;
*pointerbyte = temp;
}
//----------------------------------------------------------------------
// Serial check
//----------------------------------------------------------------------
Serial.print("Write ");Serial.print(Size);Serial.println(" bytes from DB1.DBB0");
// Put the current tick
MarkTime();
Result=Client.WriteArea(S7AreaDB, // We are requesting DB access
1, // DB Number = 1
0, // Start from byte N.0
Size, // We need "Size" bytes
bytes); // Put them into our target (Buffer or PDU)
if (Result==0)
{
ShowTime();
Dump(Target, Size);
}
else
CheckError(Result);
delay(500);
}
void I2C_Write(uint8_t deviceAddress, uint8_t regAddress, uint8_t data){
Wire.beginTransmission(deviceAddress);
Wire.write(regAddress);
Wire.write(data);
Wire.endTransmission();
}
// read all 14 register
void Read_RawValue(uint8_t deviceAddress, uint8_t regAddress){
Wire.beginTransmission(deviceAddress);
Wire.write(regAddress);
Wire.endTransmission();
Wire.requestFrom(deviceAddress, (uint8_t)14);
AccelX = (((int16_t)Wire.read()<<8) | Wire.read());
AccelY = (((int16_t)Wire.read()<<8) | Wire.read());
AccelZ = (((int16_t)Wire.read()<<8) | Wire.read());
Temperature = (((int16_t)Wire.read()<<8) | Wire.read());
GyroX = (((int16_t)Wire.read()<<8) | Wire.read());
GyroY = (((int16_t)Wire.read()<<8) | Wire.read());
GyroZ = (((int16_t)Wire.read()<<8) | Wire.read());
}
//configure MPU6050
void MPU6050_Init(){
delay(150);
I2C_Write(MPU6050SlaveAddress, MPU6050_REGISTER_SMPLRT_DIV, 0x07);
I2C_Write(MPU6050SlaveAddress, MPU6050_REGISTER_PWR_MGMT_1, 0x01);
I2C_Write(MPU6050SlaveAddress, MPU6050_REGISTER_PWR_MGMT_2, 0x00);
I2C_Write(MPU6050SlaveAddress, MPU6050_REGISTER_CONFIG, 0x00);
I2C_Write(MPU6050SlaveAddress, MPU6050_REGISTER_GYRO_CONFIG, 0x00);//set +/-250 degree/second full scale
I2C_Write(MPU6050SlaveAddress, MPU6050_REGISTER_ACCEL_CONFIG, 0x00);// set +/- 2g full scale
I2C_Write(MPU6050SlaveAddress, MPU6050_REGISTER_FIFO_EN, 0x00);
I2C_Write(MPU6050SlaveAddress, MPU6050_REGISTER_INT_ENABLE, 0x01);
I2C_Write(MPU6050SlaveAddress, MPU6050_REGISTER_SIGNAL_PATH_RESET, 0x00);
I2C_Write(MPU6050SlaveAddress, MPU6050_REGISTER_USER_CTRL, 0x00);
}
@methaqali

This comment has been minimized.

Copy link

@methaqali methaqali commented Jan 8, 2019

nice, can you make code for LSIS plc?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment