With the declanation of "volatile", the complete code works as intended,
intil I plug in the Ethernet cable, then the error ocurrs.
I did not try the "noInterrupts()" function yet.
The code is not cleaned up yet and has a lot of commented debugging outputs and is not wiped of (small) unused variables.
Here is the complete code (500 lines) :
#include <Wire.h>
#include "DHT.h"
#include <EthernetENC.h> // for ENC28J60
#include <EthernetUdp.h> // for UDP
#define DHTpin 7
#define DHTTYPE DHT22
DHT dht(DHTpin, DHTTYPE);
IPAddress localIP(169, 254, 0, 42);
IPAddress remoteIP(169, 254, 0, 24);
//Pin Definition
const int Fan = 9;
const int Heater = 8;
const int LNAbox = 5;
const int HPApin = 4; //Muss final 4 sein!
const int WindSens = 2; //Muss final 2 sein!
//Parameter
volatile float wind_speed;
int wind_speed100;
float Dew;
float a, b, c, d, e; //formel variablen
int Tmax = 30;
int Tmin = 10;
int HS = 5; //Dew Hysteresis
unsigned long t_pulse0 = 0;
volatile unsigned long t_pulse1;
int tmin = 20; // [msec]
//Ethernet
unsigned int localPort = 10000; // local port to listen on
unsigned int remotePort = 10000; // remote port to transmit too
// Enter a MAC address
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
// An EthernetUDP instance to let us send and receive packets over UDP
EthernetUDP Udp;
//Frame Build
uint8_t frame[63];
uint8_t arr4[4], arr2[2];
uint32_t SYNC;
unsigned long sync = 0x1ACFFC1D;
uint16_t StatusBits;
float TempLNA, HygroLNA, GyroX, GyroY, GyroZ, CurrLNA, TempBox, HygroBox;
short TmaxLNA, TminLNA, TmaxBox, TminBox, HygroStep = 5, Wind;
uint16_t ComBits;
uint8_t ComTmaxLNA, ComTminLNA, ComTmaxBox, ComTminBox, ComHygroStep;
bool PeltierPWR, PeltierSW, FanIN, FanOUT, LNA, BoxHeater, BoxFan, LNAboxPWR, HPA, CRCok;
bool comPeltierPWR, comPeltierSW, comFanIN, comFanOUT, comLNA, comBoxHeater, comBoxFan, comLNAboxPWR, comHPA, comOverride;
// print IPAdress and port
void displayIPaddress(const IPAddress address, unsigned int port) {
Serial.print(" IP ");
for (int i = 0; i < 4; i++) {
Serial.print(address[i], DEC);
if (i < 3) Serial.print(".");
}
Serial.print(" port ");
Serial.println(port);
}
void displayMACaddress(byte address[]) {
Serial.print("MAC address ");
for (int i = 0; i < 6; i++) {
Serial.print("0x");
Serial.print(address[i], HEX);
if (i < 5) Serial.print(".");
}
Serial.println();
}
uint16_t checksumCalculator(uint8_t * data, uint16_t length){
uint16_t curr_crc = 0x0000;
uint8_t sum1 = (uint8_t) curr_crc;
uint8_t sum2 = (uint8_t) (curr_crc >> 8);
int index;
for(index = 0; index < length; index = index+1)
{
sum1 = (sum1 + data[index]) % 255;
sum2 = (sum2 + sum1) % 255;
}
return (sum2 << 8) | sum1;
}
uint32_t get32BitWord(uint8_t * data, int pos){
uint32_t byte0 = data[pos];
uint32_t byte1 = data[pos+1];
uint32_t byte2 = data[pos+2];
uint32_t byte3 = data[pos+3];
uint32_t val = (byte0 << 24) + (byte1 << 16) + (byte2 << 8) + byte3;
return val;
}
void SerialInput(){
const int BUFFER_SIZE = 130; //130
uint8_t buf[BUFFER_SIZE]; // directly casted to 1 Byte!
uint16_t CRC;
if (Serial.available() > 0) {
//Serial.println("Received");
uint8_t seek = Serial.readBytes(buf, BUFFER_SIZE);
/*for(int n=0; n<63; n++){
sframe[n] = (uint8_t)buf[n];
}*/
Serial.println("\nBuffer:"); // Show read bytes for Debugging
for(int i=0; i<130; i++){
Serial.print(buf[i], HEX);
}
for(int i=0; i<65; i++){
if(buf[i]==0x1a && buf[i+1]==0xcf && buf[i+2]==0xfc && buf[i+3]==0x1d){ // seek SYNC word
//Serial.println("Start found!");
for(int n=0; n<63; n++){
frame[n] = buf[n+i]; // write found frame into Frame Array
}
};
}
CRC = (frame[62] << 8) + frame[61];
uint16_t crc = checksumCalculator(frame,61);
SYNC = get32BitWord(frame, 0);
if(CRC == 0){
//Serial.println("CRC = 0");
CRCok = false;
bitWrite(StatusBits, 6, 0);
if(SYNC == sync){
Serial.println("\nRx Frame CRC Broken");
}
else{
Serial.println("\nRx Frame Broken");
}
return;
}
if((crc == CRC) && (sync == SYNC)){
//Serial.println("OK");
StatusBits = (frame[4] << 8) + frame[5];
/*TempLNA = get32BitWord(frame, 6); //Not needed on this controller
HygroLNA = get32BitWord(frame, 10);
GyroX = get32BitWord(frame, 14);
GyroY = get32BitWord(frame, 18);
GyroZ = get32BitWord(frame, 22);
CurrLNA = get32BitWord(frame, 26);
Wind = (frame[30] << 8) + frame[31];
TempBox = get32BitWord(frame, 32);
HygroBox = get32BitWord(frame, 36);
TmaxLNA = (frame[40] << 8) + frame[41];
TminLNA = (frame[42] << 8) + frame[43];
HygroStep = (frame[48] << 8) + frame[49];
/*Read Status Bits*/
/*PeltierPWR = bitRead(StatusBits, 15);
PeltierSW = bitRead(StatusBits, 14);
FanIN = bitRead(StatusBits, 13);
FanOUT = bitRead(StatusBits, 12);
LNA = bitRead(StatusBits, 11);
BoxHeater = bitRead(StatusBits, 10);
BoxFan = bitRead(StatusBits, 9);
LNAboxPWR = bitRead(StatusBits, 8);
HPA = bitRead(StatusBits, 7);*/
CRCok = true;
bitWrite(StatusBits, 6, 1);
}
else{
CRCok = false;
bitWrite(StatusBits, 6, 0);
if(SYNC == sync){
Serial.println("\nRx Frame CRC Broken");
}
else{
Serial.println("\nRx Frame Broken");
}
for(int i=0; i<63; i++){
Serial.print(frame[i], HEX);}
Serial.println("No Rx Frame");
for(int i=6; i<30; i++){ // delete Data from LNA Box
frame[i] = 0;}
}
}
else{
Serial.println("No Rx Frame");
for(int i=6; i<30; i++){ // delete Data from LNA Box
frame[i] = 0;}
return;
}
}
void floatToByte(byte* arr4, float value){
long l = *(long*) &value;
arr4[3] = l & 0x00FF;
arr4[2] = (l >> 8) & 0x00FF;
arr4[1] = (l >> 16) & 0x00FF;
arr4[0] = l >> 24;
}
void longToByte(byte* arr4, long value){ //for Sync Word
long l = *(long*) &value;
arr4[3] = l & 0x00FF;
arr4[2] = (l >> 8) & 0x00FF;
arr4[1] = (l >> 16) & 0x00FF;
arr4[0] = l >> 24;
}
void intToByte(byte* arr2, int value){
short s = *(short*) &value;
arr2[1] = s & 0x00FF;
arr2[0] = s >> 8;
}
void measure(){
unsigned long dt;
t_pulse0 = t_pulse1;
t_pulse1 = millis();
dt = t_pulse1-t_pulse0;
if(dt>0){
if(dt>tmin){
wind_speed = 1000/(0.5*dt); // 1U/s = 2m/s
//Serial.println((String)"\n Delta: "+dt);
dt = 0;
}
else{
return;
}
}
else{
//wind_speed = 0;
}
}
void UDPOutput(){
longToByte(arr4, sync);
frame[0] = arr4[0];
frame[1] = arr4[1];
frame[2] = arr4[2];
frame[3] = arr4[3];
intToByte(arr2, StatusBits);
frame[4] = arr2[0];
frame[5] = arr2[1];
intToByte(arr2, wind_speed100);
frame[30] = arr2[0];
frame[31] = arr2[1];
floatToByte(arr4, TempBox);
frame[32] = arr4[0];
frame[33] = arr4[1];
frame[34] = arr4[2];
frame[35] = arr4[3];
floatToByte(arr4, HygroBox);
frame[36] = arr4[0];
frame[37] = arr4[1];
frame[38] = arr4[2];
frame[39] = arr4[3];
intToByte(arr2, TmaxBox);
frame[44] = arr2[0];
frame[45] = arr2[1];
intToByte(arr2, TminBox);
frame[46] = arr2[0];
frame[47] = arr2[1];
intToByte(arr2, HygroStep);
frame[48] = arr2[0];
frame[49] = arr2[1];
/*intToByte(arr2, ComBits);
frame[50] = arr2[0];
frame[51] = arr2[1];*/
/*frame[52] = ComTmaxLNA; //ComFrame[52];
frame[53] = ComTminLNA; //ComFrame[53];
frame[54] = ComTmaxBox; //ComFrame[54];
frame[55] = ComTminBox; //ComFrame[55];
frame[56] = ComHygroStep; //ComFrame[56];*/
frame[58] = 0;
frame[59] = 0;
frame[60] = 0;
uint16_t crc = checksumCalculator(frame,61);
intToByte(arr2, crc);
frame[61] = arr2[1];
frame[62] = arr2[0];
/*Serial.println();
for(int i=0; i<63; i++){
Serial.print(frame[i], HEX);
}*/
Udp.begin(localPort);
Udp.beginPacket(remoteIP, remotePort); // transmit data
for(int i=0; i<63; i++){
Udp.write(frame[i]);
}
Udp.endPacket();
}
void UDPpass(){
uint8_t ComFrame[63];
int packetSize = Udp.parsePacket();
if (packetSize) {
Udp.read(ComFrame, packetSize);
/*Serial.println();
for(int i=0; i<63; i++){
Serial.print(ComFrame[i], HEX);
}
Serial.println();*/
for(int i=0; i<63; i++){
ComFrame[i] = (uint8_t)ComFrame[i];}
//Serial.print(ComFrame[i], HEX);}
ComBits = (ComFrame[50] << 8) + ComFrame[51];
ComTmaxLNA = ComFrame[52];
ComTminLNA = ComFrame[53];
ComTmaxBox = ComFrame[54];
ComTminBox = ComFrame[55];
ComHygroStep = ComFrame[56];
if(ComTmaxLNA == 0){TmaxLNA = Tmax;}
if(ComTminLNA == 0){TminLNA = Tmin;}
if(ComTmaxBox == 0){TmaxBox = Tmax;}
if(ComTminBox == 0){TminBox = Tmin;}
if(ComHygroStep == 0){HygroStep = HS;}
/*Read Command Bits*/
/*comPeltierPWR = bitRead(ComBits, 15);
comPeltierSW = bitRead(ComBits, 14);
comFanIN = bitRead(ComBits, 13);
comFanOUT = bitRead(ComBits, 12);
comLNA = bitRead(ComBits, 11);*/
comBoxHeater = bitRead(ComBits, 10);
comBoxFan = bitRead(ComBits, 9);
comLNAboxPWR = bitRead(ComBits, 8);
comHPA = bitRead(ComBits, 7);
comOverride = bitRead(ComBits, 6);
uint16_t crc = checksumCalculator(ComFrame,61);
intToByte(arr2, crc);
ComFrame[61] = arr2[1];
ComFrame[62] = arr2[0];
for(int i=0; i<63; i++){
Serial.write(ComFrame[i]);
//Serial.print(frame[i], HEX);
}
}
}
void setup(){
Serial.begin(9600);
pinMode(DHTpin, INPUT);
pinMode(Fan, OUTPUT);
pinMode(Heater, OUTPUT);
pinMode(LNAbox, OUTPUT);
pinMode(HPA, OUTPUT);
pinMode(WindSens, INPUT_PULLUP);
dht.begin();
attachInterrupt(digitalPinToInterrupt(WindSens), measure, FALLING);
Ethernet.init(10); // Most Arduino shields
mac[5] = localIP[3]; // change default MAC address
displayMACaddress(mac);
Ethernet.begin(mac, localIP);
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) { // seems not to work, to be Deleted ???
Serial.println("Ethernet cable is not connected.");
}
Udp.begin(localPort); // start UDP
Serial.print("Ethernet UDP started ");
displayIPaddress(localIP, localPort);
//Serial.println(UDP_TX_PACKET_MAX_SIZE);
}
void loop(){
UDPpass();
SerialInput();
HygroBox = dht.readHumidity();
TempBox = dht.readTemperature();
if(millis()-t_pulse1 > 3000){ // no Wind recognition
wind_speed = 0;
}
Serial.println((String)wind_speed+" m/s");
/*Serial.println(t_pulse0);
Serial.println(t_pulse1);
Serial.println(t_pulse1-t_pulse0);*/
wind_speed100 = wind_speed*100;
a = 17.62*TempBox;
b = 243.12+TempBox;
c = 17.62*243.12;
d = HygroBox/100;
e = (a/b+log(d))/(c/b-log(d));
Dew = 243.12*e;
//Serial.println((String)Dew+" deg Dewpoint");
if(comOverride){
if(comLNAboxPWR){
digitalWrite(LNAbox, HIGH);
bitWrite(StatusBits, 8, 1);}
else{
digitalWrite(LNAbox, LOW);
bitWrite(StatusBits, 8, 0);}
if(comHPA){
digitalWrite(HPApin, HIGH);
bitWrite(StatusBits, 7, 1);}
else{
digitalWrite(HPApin, LOW);
bitWrite(StatusBits, 7, 0);}
if(comBoxHeater){
digitalWrite(Heater, HIGH);
bitWrite(StatusBits, 10, 1);}
else{
digitalWrite(Heater, LOW);
bitWrite(StatusBits, 10, 0);}
if(comBoxFan){
digitalWrite(Fan, HIGH);
bitWrite(StatusBits, 9, 1);}
else{
digitalWrite(Fan, LOW);
bitWrite(StatusBits, 9, 0);}
if(ComTmaxBox!=0){
Tmax = ComTmaxBox;
TmaxBox = ComTmaxBox;}
if(ComTminBox!=0){
Tmin = ComTminBox;
TminBox = ComTminBox;}
if(ComHygroStep!=0){
HS = ComHygroStep;
HygroStep = ComHygroStep;}
}
else{
if(TempBox>Tmax){
digitalWrite(Fan, HIGH);
bitWrite(StatusBits, 9, 1);}
else{
digitalWrite(Fan, LOW);
bitWrite(StatusBits, 9, 0);}
if(TempBox<Dew+HygroStep || TempBox<TminBox){
digitalWrite(Heater, HIGH);
bitWrite(StatusBits, 10, 1);}
else{
digitalWrite(Heater, LOW);
bitWrite(StatusBits, 10, 0);}
}
bitWrite(StatusBits, 0, 0);
bitWrite(StatusBits, 1, 0);
bitWrite(StatusBits, 2, 0);
bitWrite(StatusBits, 3, 0);
bitWrite(StatusBits, 4, 0);
bitWrite(StatusBits, 5, 0);
//bitWrite(StatusBits, 8, 1); //LNA Box PWR ON ----- Dummy for Test
//Serial.println(StatusBits, BIN);
UDPOutput();
delay(673); //uneven number to avoid congruence
}