Announcement

Collapse
No announcement yet.

Arduino/enet hangs - serial mon clears it

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    Arduino/enet hangs - serial mon clears it

    Hey all:

    I've run into a bizarre situation I'm wondering if anyone can suggest a fix. I've got the beta version of the sketch that I've added my own code to - I'm communicating over Ethernet. The problem I have is that after a period of time (20-40 min) the Arduino drops off the internet - the plug in shows an error and I can't ping the IP address. In order to clear it all I have to do is open the serial monitor. There is no output on the serial monitor and I don't have any serial output code written so I'm sort of confused as to how this can be happening....is there something about serial monitor I haven't been told!?

    anyways hoping someone's already been through this - thanks!

    #2
    Sorry I missed this post.
    The serial monitor will reset the board when started. Can you post you code so we can check it. What boards do you have and are they genuine Arduino.

    Greig.

    Sent from my SM-G925F using Tapatalk
    Zwave = Z-Stick, 3xHSM100� 7xACT ZDM230, 1xEverspring SM103, 2xACT HomePro ZRP210.
    X10 = CM12U, 2xAM12, 1xAW10, 1 x TM13U, 1xMS13, 2xHR10, 2xSS13
    Other Hardware = ADI Ocelot + secu16, Global Cache GC100, RFXtrx433, 3 x Foscams.
    Plugings = RFXcom, ActiveBackup, Applied Digital Ocelot, BLDeviceMatrix, BLGarbage, BLLAN, Current Cost, Global Cache GC100,HSTouch Android, HSTouch Server, HSTouch Server Unlimited, NetCAM, PowerTrigger, SageWebcamXP, SqueezeBox, X10 CM11A/CM12U.
    Scripts =
    Various

    Comment


      #3
      I've been reading elsewhere on this topic - W5100 ethernet hanging has been a very active topic, lots of pointers to hardware issues. The board is RioRand, I got it off amazon and note it is currently unavailable! If I'm going to buy another board, would either the W5200 or W5500 be a better bet for reliability? This is going into an irrigation system so it needs to be rock solid for many months at a time.

      I'm pretty confident about my code but any inputs you have would be welcome.


      //#define DEBUG
      #include <WString.h>
      #include <SD.h>
      int val=1, oldval=1;
      int HS_Inputs[14] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
      int HS_Inputs_old [14] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
      unsigned long previousflowmillis = 0, flowmillis = 0;
      int arriving = 0, departing = 0;
      int i;
      int flow_timer;
      String outline;
      bool initial_pass = true;
      /* HS_Outputs
      * 0 unused
      * 1 flow_counter
      * 2 error_state
      * 3 raised bed valve
      * 4 front yard valve
      * 5 courtyard valve
      * 6 east orchard valve
      * 7 west hill valve
      * 8 north hill valve
      * 9 fountain fill valve
      * 10 east gardens valve
      * 11 house water valve
      * 12 booster pump
      * 13 fountain pump
      * 14 lower_motion
      * 15 upper_motion
      * 16 guest_arriving
      * 17 guest_departing
      * 18 low water switch
      * 19 normal water switch
      * 20 high water switch
      * 21 water flow switch
      */
      int pins [22] = {0,0,0,-22,-23,-24,-25,-26,-27,-28,-29,-30,-31,-32,49,48,0,0,47,46,45,44};
      int pins_old[22] ={0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};
      const byte raised_bed=3, front_yard=4, courtyard=5, east_orchard=6;
      const byte west_hill=7, north_hill=8, fountain_fill=9, east_gardens=10;
      const byte fountain_pump=13, booster_pump=12, house_water=11;
      const byte lower_motion=14, upper_motion=15, guest_arrived=16, guest_departed=17;
      const byte low_water=18, normal_water=19, high_water=20, water_flow=21;
      const byte HS_flow_timer=1, HS_Error=2;
      const byte CONTROL_ON=0, CONTROL_OFF=1;
      const byte INPUT_ON=0, INPUT_OFF=1;
      const byte pin_count=22, valv_count=14;
      const byte irr_valv_start=3, irr_valv_end=10;
      const int max_time = 16000;
      const int dump_delay = 2;
      int dump_timer = 0;
      int dump_valve[3] = {raised_bed, front_yard, courtyard};
      unsigned long dumpmillis=0, prevdumpmillis=0;

      //For serial set to 0 and for Ethernet set to 1
      #define ISIP 1
      //Do NOT modify these
      #if ISIP == 1
      #include <EEPROM.h>
      #include <SPI.h>
      #include <Ethernet.h>
      #include <EthernetUdp.h>
      #endif
      /************************************************************
      *Arduino to Homeseer 3 Plugin API written by Enigma Theatre.*
      * V1.0.0.81 *
      * *
      *******Change the values below only*************************
      */


      //Address of the board.
      const byte BoardAdd = 1;

      #if ISIP == 1
      // Enter a MAC address and IP address for your board below.
      byte mac[] = {0x00, 0xAA, 0xBB, 0xCC, 0xDE, 0x01};

      // The IP address will be dependent on your local network.
      IPAddress ip(192,168,xxx,xxx); //IP entered in HS config.
      const unsigned int localPort = 55100; //port entered in HS config.
      IPAddress HomeseerIP(192,168,xxx,xxx); //Homeseer IP address
      IPAddress ServerIP(EEPROM.read(2),EEPROM.read(3),EEPROM.read(4),EEPROM .read(5));
      byte EEpromVersion = EEPROM.read(250);
      #endif


      //************Do not change anything in Here*****************
      int FromHS[14]; // *
      boolean IsConnected = false; // *
      #if ISIP == 1 // *
      char packetBuffer[UDP_TX_PACKET_MAX_SIZE]; // *
      EthernetUDP Udp; // *
      const unsigned int ServerPort = 8888; // *
      #endif // *
      void(* resetFunc) (void) = 0; // *
      //***********************************************************


      /*
      SETUP ROUTINE
      */
      void setup() {
      HSSetup();
      //************************
      //Add YOUR SETUP HERE;
      //************************

      #ifdef DEBUG
      Serial.begin (9600);
      #endif
      pinMode(4,OUTPUT);
      digitalWrite(4,HIGH);
      for (i=0; i<=pin_count; i++){
      if (pins[i] > 0){
      pinMode (pins[i], INPUT_PULLUP);
      }
      else if (pins[i] < 0){
      pinMode (abs(pins[i]), OUTPUT);
      digitalWrite(abs(pins[i]), HIGH);
      }
      }
      #ifdef DEBUG
      Serial.println ("Setup Complete");
      #endif
      }



      /*
      MAIN LOOP ROUTINE
      */
      void loop() {

      #if ISIP == 1
      IsUDP();
      #endif
      /*Execute ONLY when HomeSeer is connected*/
      if (IsConnected == true) {
      if (initial_pass) {
      for (i=1; i<pin_count; i++) {
      SendToHS (i,pins_old[i]);
      }
      initial_pass = false;
      }
      }
      else{
      initial_pass = true;
      }

      read_all_inputs();
      /*Execute regardless of connection status*/

      // high water level processing

      if (pins_old[high_water]==INPUT_ON and pins_old[booster_pump]==CONTROL_OFF){
      if (dumpmillis - prevdumpmillis > 60000){
      dump_timer += 1;
      prevdumpmillis = dumpmillis;
      #ifdef DEBUG
      Serial.println(dump_timer);
      #endif
      }
      if (dump_timer>dump_delay and pins_old[booster_pump]==CONTROL_OFF){
      start_water ();
      for (i=0; i<3; i++) {
      digitalWrite(abs(pins[dump_valve[i]]), HIGH);

      }
      #ifdef DEBUG
      Serial.println("dump started");
      #endif

      }
      dumpmillis = millis();
      }

      if (dumpmillis > 0){
      if (pins_old[high_water] == INPUT_OFF){
      if (pins_old[booster_pump]==CONTROL_ON){
      stop_water();
      shut_all_valves();
      }
      dumpmillis = 0;
      dump_timer = 0;
      }
      }

      // flow timer update once per second if running
      if (flowmillis != 0){
      flowmillis = millis();
      if (flowmillis - previousflowmillis >= 1000){
      previousflowmillis = flowmillis;
      flow_timer+=1;
      if (flow_timer % 10 == 0) SendToHS(1,flow_timer);
      }
      if (flow_timer > max_time) {
      stop_water ();
      shut_all_valves ();
      #ifdef DEBUG
      Serial.println ("ran too long");
      #endif
      SendToHS(HS_Error, 5);
      }
      else if ((digitalRead(abs(pins[booster_pump])) ==1) and (digitalRead(pins[low_water]) > 0 )) {
      stop_water ();
      shut_all_valves ();
      #ifdef DEBUG
      Serial.println (digitalRead(abs(pins[booster_pump])));
      Serial.println ("ran out of water");
      #endif
      SendToHS(HS_Error, 6);
      }
      }
      /* guest processing*/

      if (pins_old[lower_motion] == INPUT_ON or pins_old[upper_motion] == INPUT_ON){
      if (arriving == 0 and pins_old[lower_motion] == INPUT_ON and pins_old[upper_motion] == INPUT_OFF){
      arriving = 1;
      }
      if (arriving ==1){
      if (pins_old[upper_motion] == INPUT_ON){
      #ifdef DEBUG
      Serial.println("guest arrived");
      #endif
      SendToHS (guest_arrived, INPUT_ON);
      arriving = 2;
      }
      else if (pins_old[lower_motion] == INPUT_OFF){
      arriving =0;
      }
      }

      if (departing == 0 and pins_old[upper_motion] == INPUT_ON and pins_old[lower_motion] == INPUT_OFF){
      departing = 1;
      }
      if (departing ==1){
      if (pins_old[lower_motion] == INPUT_ON){
      #ifdef DEBUG
      Serial.println("guest departed");
      #endif
      SendToHS (guest_departed, INPUT_ON);
      departing = 2;
      }
      else if (pins_old[upper_motion] == INPUT_OFF){
      departing = 0;
      }
      }
      }
      else {
      arriving=0;
      departing=0;
      if (arriving == 2 or departing == 2){
      SendToHS (guest_arrived, INPUT_OFF);
      SendToHS (guest_departed, INPUT_OFF);
      }
      }


      for ( i = irr_valv_start; i <=irr_valv_end; i++){
      if (input_becomes(255, i)){
      #ifdef DEBUG
      outline = "Input: ";
      outline = outline + i;
      outline = outline + " on";
      Serial.println(outline);
      #endif
      if (FromHS[0] == 0) start_water();
      digitalWrite (abs(pins[i]), LOW);
      }
      }
      for ( i = irr_valv_start; i <=irr_valv_end; i++){
      if (input_becomes(0, i)){
      #ifdef DEBUG
      outline = "Input: ";
      outline = outline + i;
      outline = outline + " off";
      Serial.println(outline);
      #endif
      SendToHS (2, 0);
      if (FromHS[0] == 0) stop_water();
      digitalWrite (abs(pins[i]), HIGH);
      }
      }

      if (input_becomes(255, fountain_pump)) {
      digitalWrite (abs(pins[fountain_pump]), LOW);
      #ifdef DEBUG
      Serial.println("fountain pump On");
      #endif
      }
      if (input_becomes(255, booster_pump) and (FromHS[0]>0)) {
      digitalWrite (abs(pins[booster_pump]), LOW);
      flowmillis = millis ();
      #ifdef DEBUG
      Serial.println("booster pump On");
      #endif
      }
      if (input_becomes(255, house_water) and (FromHS[0]>0)) {
      digitalWrite (abs(pins[house_water]), LOW);
      flowmillis = millis ();
      #ifdef DEBUG
      Serial.println("house water On");
      #endif
      }
      if (input_becomes(0, fountain_pump)) {
      digitalWrite (abs(pins[fountain_pump]), HIGH);
      #ifdef DEBUG
      Serial.println("fountain pump Off");
      #endif
      }
      if (input_becomes(0, booster_pump)) {
      digitalWrite (abs(pins[booster_pump]), HIGH);
      flowmillis = 0;
      flow_timer = 0;
      SendToHS(HS_flow_timer,flow_timer);
      #ifdef DEBUG
      Serial.println("booster pump Off");
      #endif
      }
      if (input_becomes(0, house_water)) {
      digitalWrite (abs(pins[house_water]), HIGH);
      flowmillis = 0;
      flow_timer = 0;
      SendToHS(HS_flow_timer,flow_timer);
      #ifdef DEBUG
      Serial.println("house water Off");
      #endif
      }
      /* end loop */
      }


      /*
      READ ALL INPUTS ROUTINE
      */
      void read_all_inputs (){
      for (i=0; i<pin_count; i++){
      if (abs(pins[i]) > 0) {
      val=digitalRead(abs(pins[i]));
      if (val != pins_old[i]){
      pins_old[i]=val;
      #ifdef DEBUG
      Serial.print(i);
      Serial.print(" ");
      Serial.println(val);
      #endif
      SendToHS(i,val);
      }
      }
      }
      }


      /*
      SHUT OFF ALL VALVES ROUTINE
      */
      void shut_all_valves (){
      for (i=3; i<=13; i++){
      if (abs(pins[i]) != 0) {
      digitalWrite (abs(pins[i]), HIGH);
      }
      }
      }

      /*
      START WATER FLOW ROUTINE
      */
      void start_water(){
      if ((FromHS[2] > 0) or (digitalRead(pins[low_water]) == INPUT_OFF)){
      #ifdef DEBUG
      Serial.println (digitalRead(pins[low_water]));
      Serial.println ("Turning on House Water Valve");
      #endif
      digitalWrite (abs(pins[house_water]), LOW);
      }
      else {
      #ifdef DEBUG
      Serial.println (digitalRead(pins[low_water]));
      Serial.println ("Turning on booster pump");
      #endif
      digitalWrite (abs(pins[booster_pump]), LOW);
      }
      flowmillis = millis();
      }


      /*
      STOP WATER FLOW ROUTINE
      */
      void stop_water(){
      #ifdef DEBUG
      Serial.println ("Turning off House Water Valve");
      Serial.println ("Turning off booster pump");
      #endif
      digitalWrite (abs(pins[house_water]), HIGH);
      digitalWrite (abs(pins[booster_pump]), HIGH);
      flowmillis = 0;
      flow_timer = 0;
      SendToHS(HS_flow_timer,flow_timer);
      }



      /*
      CHECK FOR HOMESEER INPUT CHANGES ROUTINE
      */
      bool input_becomes (int target, int input_index){
      bool result;
      result = false;
      if ((FromHS[input_index]== target) && (target != HS_Inputs_old[input_index])){
      HS_Inputs_old[input_index] = target;
      result = true;
      }
      return result;
      }





















































      /*
      ARDUINO COMMUNCICATIONS ROUTINEs
      */

      const char* Version = "API1.0.0.81";

      byte Byte1,Byte2,Byte3;
      int Byte4,Byte5;


      void HSSetup() {

      #if ISIP == 1
      if (EEpromVersion!=22) {
      ServerIP=HomeseerIP;
      EEPROM.write(2,ServerIP[0]);
      EEPROM.write(3,ServerIP[1]);
      EEPROM.write(4,ServerIP[2]);
      EEPROM.write(5,ServerIP[3]);
      EEPROM.write(250,22); //Store the version where the eeprom data layout was last changed
      EEpromVersion=22;
      }
      Ethernet.begin(mac,ip);
      Udp.begin(localPort);
      Udp.setTimeout(0);
      delay(1000);
      SendConnect();
      #else
      Serial.begin(115200);
      Serial.flush();
      Serial.setTimeout(0);
      delay(1000);
      Serial.print("Connect ");
      Serial.println(BoardAdd);
      #endif

      IsConnected = false;

      }

      void SendConnect()
      {
      #if ISIP == 0
      Serial.print("Connect ");
      Serial.println(BoardAdd);
      #else
      Udp.beginPacket(ServerIP,ServerPort); //First send a connect packet to the dynamic IP stored in eeprom
      Udp.print("Connect ");
      Udp.print(BoardAdd);
      Udp.endPacket();
      if (ServerIP!=HomeseerIP) {
      Udp.beginPacket(HomeseerIP,ServerPort); //Then if the stored value doesn't match the pre-specified one, send a connect packet there also
      Udp.print("Connect ");
      Udp.print(BoardAdd);
      Udp.endPacket();
      }

      #endif
      }


      #if ISIP == 1
      void IsUDP(){
      int packetSize = Udp.parsePacket();
      if(packetSize)
      {
      IPAddress remote = Udp.remoteIP();
      Byte1 =Udp.parseInt();
      Udp.read();
      Byte2 =Udp.read();
      Byte3 =Udp.parseInt();
      Byte4 =Udp.parseInt();
      Byte5 =Udp.parseInt();
      DataEvent();
      }
      }

      #else
      void serialEvent() {
      while (Serial.available() > 0) {
      delay(17);


      Byte1 = Serial.parseInt();
      Serial.read();
      Byte2 = Serial.read();
      Byte3 = Serial.parseInt();
      Byte4 = Serial.parseInt();
      Byte5 = Serial.parseInt();
      DataEvent();
      }
      }
      #endif


      /*

      Used Data Input Cases
      D Disconnect
      r reset
      K Keepalive
      O PinMode Output Set
      d Input debounce time set
      C Connect request
      c Connection established - report current status
      */
      void DataEvent() {



      if (Byte1 == BoardAdd) {
      switch (Byte2) {

      case 'c':
      IsConnected = true;
      #if ISIP == 1
      if (Udp.remoteIP() != ServerIP) {
      ServerIP=Udp.remoteIP();
      EEPROM.write(2,ServerIP[0]);
      EEPROM.write(3,ServerIP[1]);
      EEPROM.write(4,ServerIP[2]);
      EEPROM.write(5,ServerIP[3]);
      }
      #endif

      break;

      case 'C':
      #if ISIP == 1
      Udp.beginPacket(Udp.remoteIP(), ServerPort);
      Udp.print("Version ");
      Udp.print(BoardAdd);
      Udp.print(" ");
      Udp.print(Version);
      Udp.println(" HS3");
      Udp.endPacket();

      Udp.beginPacket(Udp.remoteIP(), ServerPort);
      delay(100);
      Udp.print("Connected ");
      Udp.println(BoardAdd);
      Udp.endPacket();
      #else
      Serial.print("Version ");
      Serial.print(BoardAdd);
      Serial.print(" ");
      Serial.print(Version);
      Serial.println(" HS3");
      delay(100);
      Serial.print("Connected ");
      Serial.println(BoardAdd);
      #endif
      delay(100);
      IsConnected = false;
      break;

      case 'K':
      delay(200);
      #if ISIP == 1
      Udp.beginPacket(Udp.remoteIP(), ServerPort);
      Udp.print("Alive ");
      Udp.println(BoardAdd);
      Udp.endPacket();
      if (Udp.remoteIP() != ServerIP) {
      ServerIP=Udp.remoteIP();
      EEPROM.write(2,ServerIP[0]);
      EEPROM.write(3,ServerIP[1]);
      EEPROM.write(4,ServerIP[2]);
      EEPROM.write(5,ServerIP[3]);
      }
      #else
      Serial.print("Alive ");
      Serial.println(BoardAdd);
      #endif
      break;

      case 'r':
      delay(200);
      resetFunc(); //call reset
      break;

      case 'O':
      FromHS[Byte3] = Byte4;
      break;

      case 'D':
      IsConnected = false;
      break;
      }
      }
      }

      void SendToHS(byte Device, long Data){
      if (IsConnected == true) {
      #if ISIP == 1
      Udp.beginPacket(Udp.remoteIP(), ServerPort);
      Udp.print(BoardAdd);
      Udp.print(" API ");
      Udp.print(Device);
      Udp.print(" ");
      Udp.print(Data);
      Udp.endPacket();
      #else
      Serial.print(BoardAdd);
      Serial.print(" API ");
      Serial.print(Device);
      Serial.print(" ");
      Serial.println(Data);
      #endif
      }
      }

      void SendToHS(byte Device, int Data){
      if (IsConnected == true) {
      #if ISIP == 1
      Udp.beginPacket(Udp.remoteIP(), ServerPort);
      Udp.print(BoardAdd);
      Udp.print(" API ");
      Udp.print(Device);
      Udp.print(" ");
      Udp.print(Data);
      Udp.endPacket();
      #else
      Serial.print(BoardAdd);
      Serial.print(" API ");
      Serial.print(Device);
      Serial.print(" ");
      Serial.println(Data);
      #endif
      }
      }

      void SendToHS(byte Device, float Data){
      if (IsConnected == true) {
      #if ISIP == 1
      Udp.beginPacket(Udp.remoteIP(), ServerPort);
      Udp.print(BoardAdd);
      Udp.print(" API ");
      Udp.print(Device);
      Udp.print(" ");
      Udp.print(Data);
      Udp.endPacket();
      #else
      Serial.print(BoardAdd);
      Serial.print(" API ");
      Serial.print(Device);
      Serial.print(" ");
      Serial.println(Data);
      #endif
      }
      }

      Comment


        #4
        I had a question about one of your predefined sections. I have 14 variables defined that are inputs - I changed the definition of FromHS[10] which is what you had to FromHS[14] which is what I think it should be - but is there something I'm missing?

        //************Do not change anything in Here*****************
        int FromHS[14]; // *
        boolean IsConnected = false; // *
        #if ISIP == 1 // *
        char packetBuffer[UDP_TX_PACKET_MAX_SIZE]; // *
        EthernetUDP Udp; // *
        const unsigned int ServerPort = 8888; // *
        #endif // *
        void(* resetFunc) (void) = 0; // *
        //***********************************************************

        Comment


          #5
          curiouser and curiouser...

          I pulled the ethernet shield and ran over usb for over 6 hours before the disconnect error. I ran in debug attached but dont see anything obvious. This is a mega 2560 from arduino
          Attached Files

          Comment


            #6
            I have determined the problem is focused on a connection error between the plug in and the Arduino, not an IP failure. I've been running for 5 days now with IP and see a fairly regular disconnect/reconnect:

            Feb-10 01:17:45 Arduino Plugin Board 1 Version API1.0.0.81 and Plugin Version 1.0.0.103 are compatible.
            Feb-10 01:17:45 Arduino Plugin Warning = Board: 1 has a connection ERROR. Retrying.

            I had the same issue with both the 1.0.0.36 as well as the beta and on two different hs3 servers so I'm confident that my hardware is running well.

            So far I have a workaround that is working - for the few cases (1 out of 10) when the disconnect results in a connection error I have a couple events that can get it back up so I'm good for now. If there is any info needed on the connection error please let me know

            Comment

            Working...
            X