No suelo utilizar Arduino en el trabajo, pero me surgió un encargo de llevar la señal de una bascula a un PLC (ET200SP). La bascula no poseía protocolo de comunicación, pero poseía una salida serial de 600 BPS para una pantalla repetidora (continuamente estaba imprimiendo el peso mostrado en el display)
Primero intente hacerlo con esp8266, pero la conexión era inestable
La solución fue utilizar un arduino uno,un shield ethernet, un adaptador serie ttl rs232 y un sensor de humedad SHT31. Programe un servidor modbus sobre IP para la conexión con el PLC
Soy consiente que el código no quedo bonito, pero si funcional.
#include <SPI.h>
#include <Ethernet.h>
#include <SoftwareSerial.h>
#include <Wire.h>
#include <ModbusTCPSlave.h>
#include "Adafruit_SHT31.h"
#include <avr/wdt.h>
// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
byte mac[] = {
0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED
};
IPAddress ip(192, 168,3, 4);
IPAddress dns(192, 168,3, 0);
IPAddress gateway(192, 168,3, 1);
IPAddress subnet(255, 255,255, 0);
// Initialize the Ethernet server library
// with the IP address and port you want to use
// (port 80 is default for HTTP):
char byte_incoming[16]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
char byte_ordenado[16]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
int inByte;
int indice=0;
bool leido;
bool estado_anterio;
int valor_entero;
bool enable_serial=false;
unsigned long Time_reset;
unsigned long Time_anterior;
unsigned long diferencia_Time_anterior;
unsigned long hume_y_tem_Time_anterior;
unsigned long Bit_de_vida_anterior=millis();
int temp_10;
int h_10;
int registro_bandera;
ModbusTCPSlave modbus;
EthernetServer server(4444);
uint16_t holdingRegisters[20];
Adafruit_SHT31 sht31 = Adafruit_SHT31();
SoftwareSerial testSerial(2, 3); // RX, TX
void reset(){
wdt_enable(WDTO_15MS);
Serial.println("RESET");
delay(100);
while(1){};
}
void setup() {
EthernetServer server(4444);
pinMode(LED_BUILTIN, OUTPUT);
wdt_disable();
// Open serial communications and wait for port to open:
Serial.begin(9600);
testSerial.begin(600);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}
Serial.println("Ethernet WebServer Example");
// start the Ethernet connection and the server:
Ethernet.begin(mac, ip,dns,gateway,subnet);
// Check for Ethernet hardware present
if (Ethernet.hardwareStatus() == EthernetNoHardware) {
Serial.println("Ethernet shield was not found. Sorry, can't run without hardware. :(");
while (true) {
delay(1); // do nothing, no point running without Ethernet hardware
}
}
if (Ethernet.linkStatus() == LinkOFF) {
Serial.println("Ethernet cable is not connected.");
}
// start the server
server.begin();
Serial.print("server is at ");
Serial.println(Ethernet.localIP());
modbus.configureHoldingRegisters(holdingRegisters, 20);
sht31.begin(0x44);
}
//**********************************
void loop() {
//Serial.print( Serial.print("&"));
EthernetClient client = server.available();
holdingRegisters[2]=valor_entero;
holdingRegisters[16]=temp_10;
holdingRegisters[7]=h_10;
modbus.poll(client);
//resetea si el bit de vida no cambia --------------
if ( holdingRegisters[0] != estado_anterio ) {
Bit_de_vida_anterior=millis();
estado_anterio=holdingRegisters[0];
}
//Serial.println( (millis()- Bit_de_vida_anterior));
if ((millis()- Bit_de_vida_anterior) > 10000) {
Serial.println("sin señal del bir de vida");
delay(1000);
reset();
}
// lee valor por serial++++++++++++++++++++++++++++++++++++++++++++++++
if ( testSerial.available()>=16) {
inByte = testSerial.readBytes(byte_incoming,16);
leido=true;
Serial.print("-");
}else {
// Serial.println(testSerial.available());
}
//el indice obtenido es el principio de la cadena obtenida++++++++++++++
if( leido==true){
while(testSerial.available()) {testSerial.read(); } //limpia
//Serial.print("+");
for (int i=0;i<=15;i++) {
if (byte_incoming[i]==0x0d ){
indice=i;
}
}
//-------------------------------------
if((millis()- hume_y_tem_Time_anterior) >2000){
hume_y_tem_Time_anterior=millis();
float temp = sht31.readTemperature();
float h = sht31.readHumidity();
temp_10= int (temp*100);
h_10= int (h*100);
Serial.print("Temp *C = "); Serial.print(temp_10); Serial.print("\t\t");
Serial.print("Hum. % = "); Serial.println(h_10);
}
//-------------------------------------
//bucle que ordena los bytes ++++++++++++++++++++++++++++++++++++++++++
for (int t=0;t<=15;t++) {
if ((indice+t)<=15 ){
byte_ordenado[t]=byte_incoming[indice+t];
}else if ((indice+t)>15 ){
byte_ordenado[t]=byte_incoming[indice+t-16];
}
}
// Selecciona los char con el dato de peso+++++++++++++++++++++++++++++++++++
String cadena;
cadena=String(byte_ordenado[8])+String(byte_ordenado[9])+String(byte_ordenado[10])+String(byte_ordenado[11])+String(byte_ordenado[13]);
valor_entero=cadena.toInt();
Serial.println(cadena);
}
indice = 0;
leido=false;
}
