Input_pullup doesn't work after a few days

First of all, I apologize for my poor English skills.
I might write a terrible sentence even with a translator.

I made a remote for the computer program using Wi-Fi module on MKR1000.
It works very well at first, but after few days or weeks, the pin I set as an Input_pullup's voltage keep it as low.
Because of that, the Board endlessly send 'button pressed' state to the computer.

Here is my schematic and code. What I do wrong here?

#include <SPI.h>
#include <WiFi101.h>
#include "config.h"

const int nodeNo = 1;
const long LoopLampinterval = 500;
const long CallButton_WD_Wait_Lampinterval = 300;
const long CanelButton_WD_Wait_Lampinterval = 300;
const long Msg_Send_Recv_Waitinterval = 30000;
const long WiFiResetinterval = 60000;
const long Button_Debounceinterval = 150;
//////// I worte these variables at "config.h".
//////// But I wrote here for easier to read.

char ssid[] = "ssid";
char pass[] = "password";

const char STX = (char)0x02;
const char ETX = (char)0x03;

String sSendNodeNo = "";
String sACS_Connect_Status_Value_Data = "";
String sBlue_Lamp_State = "0";
String sGreen_Lamp_State = "0";

String sSend_Call_ButtonState = "0";
String sSend_Canel_ButtonState = "0";
String sRecv_CallStatus = "0"; 
String sRecv_CanelStatus = "0";
String sCallButton_RecvWait_Lamp = "0";
String sCanelButton_RecvWait_Lamp = "0";
String sSend_Canel_ButtonState_Wait = "0";

unsigned long BlueLampMillis = 0;
unsigned long iWiFi_Reset_Millis = 0;
unsigned long CallButton_RecvWait_Millis = 0;
unsigned long CanelButton_RecvWait_Millis = 0;
unsigned long Msg_Send_RecvWait_Millis = 0;
unsigned long CallButton_Debounce_Millis = 0;
unsigned long CanelButton_Debounce_Millis = 0;

int iACS_Comm_Step = 0;
int iACS_Read_Retry = 0;
int Last_Call_ButtonState = 1;
int Last_Canel_ButtonState = 1;
int CallPin = 0;
int CancelPin = 1;

WiFiServer server(5555);

bool alreadyConnected = false;

void setup()
{
    pinMode(CallPin, INPUT_PULLUP); //CallButton
    pinMode(CancelPin, INPUT_PULLUP); //CanelButton
    pinMode(4, OUTPUT); //R
    pinMode(5, OUTPUT); //G
    pinMode(6, OUTPUT); //B
    pinMode(7, OUTPUT); //CALL
    pinMode(8, OUTPUT); //CANCEL

    WiFiJoin();
    server.begin();
}


void loop()
{    
    WiFiJoin();
    Blue_Lamp_Control();
    Msg_Send_Recv_ModuleReset();
    Call_Button();
    Canel_Button();
    CallButton_Lamp_Control();
    CanelButton_Lamp_Control();
    
    WiFiClient client = server.available();
    if (client)
    {
        if (!alreadyConnected)
        {
            client.flush();
            alreadyConnected = true;
        }

        if (client.available() > 0)
        {
            Serial.println("client connected");
            Init();
            if (ACS_Recv_Response(&client))
            {
		ErrorHandle();
                Serial.println("send to server");
                String SendData = "";
                SendData += STX;
                SendData += sSendNodeNo;
                SendData += "RD";
                SendData += sSend_Call_ButtonState;
                if(sSend_Canel_ButtonState_Wait=="0") 
                SendData += sSend_Canel_ButtonState;
                else SendData += "0";                
                SendData += ETX;
                client.print(SendData);
                client.stop();
                Update_Green_Lamp("0");
                Serial.println("client.stop"); 
                Serial.print("TX:");
                Serial.println(SendData);
                Msg_Send_RecvWait_Millis = millis();
            }
        }
    } 
}


bool ACS_Recv_Response(WiFiClient* p_clinet)
{
    bool data_receive_complete = false;

    while (p_clinet->available())
    {
        Update_Green_Lamp("1");
        char c = p_clinet->read(); 
        sACS_Connect_Status_Value_Data += c;
        Serial.write(c);
        if (c == ETX) data_receive_complete = true;
    }

    if (data_receive_complete)
    {
        Serial.println("");
        Serial.print(">>:");
        Serial.println(sACS_Connect_Status_Value_Data);
        Serial.println("transfer succes");
        String ACS_Connect_State = ACS_Connect_json_parser(sACS_Connect_Status_Value_Data);
        Serial.print(F("ACS_Connect_State:"));
        Serial.println(ACS_Connect_State);
        return true;
    }
    return false;
}


String ACS_Connect_json_parser(String s)
{
    String val;
    val = s.substring(1, 9);
    sSendNodeNo = val.substring(0, 2);
    Serial.println(sSendNodeNo);

    sRecv_CallStatus = val.charAt(4);
    Button_Reset(sRecv_CallStatus);

    sRecv_CanelStatus = val.charAt(5);
    //Button_Reset(sRecv_CanelStatus);

    Msg_Send_RecvWait_Millis = millis();
    return val;
}
void WiFiJoin()
{
    if (WiFi.status() == WL_NO_SHIELD)
    {
        while (true) ;
    }

    while (WiFi.status() != WL_CONNECTED)
    {
        Serial.print("Attempting to connect to ");
        Serial.println(ssid);

        Update_Green_Lamp("0");
        Update_Blue_Lamp("0");
        unsigned long ResetMillis = millis();
        if (ResetMillis - iWiFi_Reset_Millis >= WiFiResetinterval)
        {
            iWiFi_Reset_Millis = ResetMillis;
            NVIC_SystemReset();
        }

        Update_Rad_Lamp("1");
        delay(500);

        IPAddress ip = IPAddress(192, 168, 1, 100 + nodeNo);
        IPAddress subnet(255, 255, 255, 0);
        WiFi.config(ip, subnet);

        WiFi.begin(ssid, pass);
        Update_Rad_Lamp("0");
        delay(500);

        Serial.println("WiFi connected.");
        printWiFiStatus();
    }
}


void printWiFiStatus()
{
    Serial.print("SSID: ");
    Serial.println(WiFi.SSID());

    IPAddress ip = WiFi.localIP();
    Serial.print("IP Address:");
    Serial.println(ip);

    long rssi = WiFi.RSSI();
    Serial.print("signal strength(RSSI):");
    Serial.print(rssi);
    Serial.println(" dBm");

    Serial.print("millis: ");
    Serial.println(millis());

    Serial.print("Msg_Send_RecvWait_Millis: ");
    Serial.println(Msg_Send_RecvWait_Millis);
}

void Blue_Lamp_Control()
{
    if (millis() - BlueLampMillis >= LoopLampinterval)
    {
        BlueLampMillis = millis();
        if (sBlue_Lamp_State.equals("0")) sBlue_Lamp_State = "1";
        else sBlue_Lamp_State = "0";
    }
    Update_Blue_Lamp(sBlue_Lamp_State);
}

void CallButton_Lamp_Control()
{
    if (sRecv_CallStatus == "2" || sSend_Call_ButtonState == "1")
    {
        sSend_Call_ButtonState = "1";
        if (millis() - CallButton_RecvWait_Millis >= CallButton_WD_Wait_Lampinterval)
        {
            CallButton_RecvWait_Millis = millis();
            if (sRecv_CallStatus == "1")
            {
                sCallButton_RecvWait_Lamp = "1";
            }
            else
            {
                if (sCallButton_RecvWait_Lamp == "0")
                    sCallButton_RecvWait_Lamp = "1";
                else
                    sCallButton_RecvWait_Lamp = "0";
            }
        }
        Update_Button1_Lamp(sCallButton_RecvWait_Lamp);
    }
    else Update_Button1_Lamp(sRecv_CallStatus);
}

void CanelButton_Lamp_Control()
{
    //if (sRecv_CanelStatus == "0" && sSend_Canel_ButtonState == "1")
    if (sRecv_CanelStatus == "2" || sSend_Canel_ButtonState == "1")
    {
        if (millis() - CanelButton_RecvWait_Millis >= CanelButton_WD_Wait_Lampinterval)
        {
            CanelButton_RecvWait_Millis = millis();
            if (sCanelButton_RecvWait_Lamp == "0") sCanelButton_RecvWait_Lamp = "1";
            else sCanelButton_RecvWait_Lamp = "0";
        }
        Update_Button2_Lamp(sCanelButton_RecvWait_Lamp);
    }
    else Update_Button2_Lamp(sRecv_CanelStatus);

}

void Msg_Send_Recv_ModuleReset()

{
    if (Msg_Send_RecvWait_Millis > 0)
    {
        if (millis() - Msg_Send_RecvWait_Millis >= Msg_Send_Recv_Waitinterval)
        {
            //Serial.print("Reset: ");
            //Serial.println("Reset");
            NVIC_SystemReset();
        }
    }
}

void Update_Rad_Lamp(String flag)
{
    if (flag.equals("1"))
        digitalWrite(4, HIGH);
    else
        digitalWrite(4, LOW);
}

void Update_Green_Lamp(String flag)
{
    if (flag.equals("1"))
        digitalWrite(5, HIGH);
    else
        digitalWrite(5, LOW);
}

void Update_Blue_Lamp(String flag)
{
    if (flag.equals("1"))
        digitalWrite(6, HIGH);
    else
        digitalWrite(6, LOW);
}

void Update_Button1_Lamp(String flag)
{
    if (flag.equals("1"))
        digitalWrite(7, HIGH);
    else
        digitalWrite(7, LOW);
}

void Update_Button2_Lamp(String flag)
{
    if (flag.equals("1"))
        digitalWrite(8, HIGH);
    else
        digitalWrite(8, LOW);
}

void Call_Button()
{
    int reading = digitalRead(CallPin);
    if(reading != Last_Call_ButtonState)
    {
      CallButton_Debounce_Millis = millis();
    }
    
    if (millis() - CallButton_Debounce_Millis > Button_Debounceinterval && reading == LOW)
    {
        sSend_Call_ButtonState = "1";
    }
    Last_Call_ButtonState = reading;
}

void Canel_Button()
{
    int reading = digitalRead(CancelPin);
    if(reading != Last_Canel_ButtonState)
    {
        CanelButton_Debounce_Millis = millis();
    }
	  if (millis() - CanelButton_Debounce_Millis > Button_Debounceinterval)
	  {
        if (sRecv_CallStatus == "2"||(sRecv_CallStatus == "0" && sSend_Call_ButtonState == "1"))
        {
    		    if (reading == LOW) sSend_Canel_ButtonState = "1";
    	  }
  	}
	  Last_Canel_ButtonState = reading;
}

void Button_Reset(String Recv_ButtonStatus)
{
    if (Recv_ButtonStatus.equals("3"))
    {
        sSend_Call_ButtonState = "0";
        sSend_Canel_ButtonState = "0";
    }
}
void ErrorHandle()
{
    if(sSend_Canel_ButtonState_Wait=="1")
    {
        sSend_Canel_ButtonState_Wait = "0";
    }
    if(sSend_Call_ButtonState == "1" && sSend_Canel_ButtonState == "1" && sRecv_CallStatus == "0" && sRecv_CanelStatus == "0")
    {
        sSend_Canel_ButtonState_Wait = "1";
    }
}

void Init()
{
    sACS_Connect_Status_Value_Data = "";
}

You may have a memory leak problem... after many days of running your program runs out of memory ... from that point random things can happen.

A potential cause of these type of problems in the use of the String classs. I see you have many.. and in most cases you don't need them.

These variables...

String sBlue_Lamp_State = "0";
String sGreen_Lamp_State = "0";

String sSend_Call_ButtonState = "0";
String sSend_Canel_ButtonState = "0";
String sRecv_CallStatus = "0";
String sRecv_CanelStatus = "0";
String sCallButton_RecvWait_Lamp = "0";
String sCanelButton_RecvWait_Lamp = "0";
String sSend_Canel_ButtonState_Wait = "0";

Can all be replaced with a single byte variable... like a char.

char sBlue_Lamp_State = '0';

or a byte...

byte sBlue_Lamp_State = 0;

or a boolean...

boolean sBlue_Lamp_State = false;

I agree with red_car. Good suggestion: boolean sBlue_Lamp_State = false;

How many volts is the voltage at the button input when the problem occurs? The pull-up resistor is to +. You need to measure at the input relative to -. I guess the clarification I made is redundant, but still... Try an external 10K pull-up resistor if you're sure the pull-up stops working.

Design and implement a heartBeat led to see what happens.

Assuming the schematic is complete and there were no links to the hardware devices you are missing resistors for each of the LEDs. This can cause the internals of the Arduino to overheat and over time fry themselves. Also there is no power supply so technically nothing will work but since it did there was something but what?

Thanks to answer. I've heard before but I was not sure that Arduino's String class doesn't do garbage collection. It was true after all.
I'll try replace all Strings to char and char*.

I think you mean after 24.8 days.

Suggest using const unsigned long instead of const long ...

const unsigned long LoopLampinterval = 500;
const unsigned long CallButton_WD_Wait_Lampinterval = 300;
const unsigned long CanelButton_WD_Wait_Lampinterval = 300;
const unsigned long Msg_Send_Recv_Waitinterval = 30000;
const unsigned long WiFiResetinterval = 60000;
const unsigned long Button_Debounceinterval = 150;

Hi, @telernet
Welcome to the forum.

Do you have current limit resistors on the LEDs connected to pins 7 and 8 ?

Can you post specs/data or where you purchased the 3 colour LED module?

Thanks for the nice clean schematic. :+1:

Thanks Tom.. :smiley: :+1: :coffee: :australia:

I don't understand what you said perfectly, but I did it what I understand.

I bring the multimeter and set it to DC voltage. And I put it to pin 1 and GND at the Arduino. It displays 194mv. Can be count to 0.
Otherwise, pin 0 and GND, that work fine yet, displays 3.24V. Almost 3.3V, what MKR1000's output Voltage.

I forgot to say that pin 0 is fine yet, but I got a same problem a lot to other MKR1000s. So, pin 0 will get busted anyway.

What is the heartBeat led?
I don't know and when I googling it, It just shows a LED signs shaped as heart.

I used a Lamp for DC 3V. not a LED. that's what I forgot to mention too.
Just in case, I leave a link for what lamp I used.
KEM Co., Ltd. - F.A. parts - LED INDICATOR - 16Φ - KLHRANU-16DT

Power comes to micro 5 pin charger which directly connected to power strip, just like phone charging.

These variable's values are not changing at all while run.
I used these just for defines the number.
Only thing that can be overflowing is 'millis()' and involved variables, but I checked that millis() can still works though the overflowing.

if (millis() - Msg_Send_RecvWait_Millis >= Msg_Send_Recv_Waitinterval)

Yes, they're not changing, but I don't think its a good idea to mix long and unsigned long in timing functions. Seems weird that in a few weeks or so the problem occurs.

Hi,
Can you please post some images of your project so we can see your component layout?

The buttons you are using are they tactile type and are you plugging them into a protoboard?

Tom.. :smiley: :+1: :coffee: :australia:

Hello

The heartBeat led is a simple optical indicator for a running sketch.

void heartBeat(int LedPin)
{
  static bool setUp = false;
  if (!setUp) pinMode (LedPin, OUTPUT), setUp = !setUp;
  digitalWrite(LedPin, (millis() / 1000) % 2);
}

and call this heartBeat() function inside the loop() function as:

heartBeat(LED_BUILTIN);

This is a simple tool to get addtional information about the behaiviour of the sketch over the run time.

Have a nice day and enjoy coding in C++.

Did you do this?

Connect 10 Kiloohm resistor (or 20K) between pin 1 and "+" (3.3v).
That should solve the problem.

I used a Lamp for DC 3V for pin 7 and 8.
I though lamp itself has the limit resistor or something like that, but I'll try attach the resistor. better than nothing.

I just googled 'RGB LED Module' and purchased just top of result.
아두이노 RGB LED 모듈 [SZH-EK058] / 디바이스마트 (devicemart.co.kr)
It written on Korean.

Your link shows it is a LED not a lamp.

"Power comes to micro 5 pin charger which directly connected to power strip, just like phone charging." What power strip?

I will wait for the Schematic, I do not like playing guessing games.


Is this enough information for you? I powered my arduino like this.
my country have lots of nonsense english word such as 'concent'(It means power sorket. real bullshit.)
Translator can't translate these words well I guess.

1 Like