-->
Page 1 of 1

How and when to use VIN as a powersource for components

PostPosted: Wed Nov 15, 2017 4:50 am
by bigalboyo
Hi,
I've been using the NodeMCU 12-e module for all my projects but I keep coming across errors when uploading to the unit if there is anything connected to the VIN or even the 3V terminals.

Basically if I power cycle the unit and there is anything connected to either the VIN or 3V supply, the unit doesn't doesn't start into either normal or flash mode (which I usually use the flash button for)

I'm currently building the classic garage door opener / monitor with reed switches and relays and using OTA which is great. My code works fine and so long as I disconnect the VIN when I try to update the firmware, it all goes fine. If I don't, I'll get connection errors when I try to upload.

Im clearly missing some information about how and when to use the VIN to power components.

Anyone want to shed some light on it please?

Current setup is as follows (tried to use tinkercad to draw a circuit diagram but alas, no NodeMCU component);

2 x SRD 5VDC-SL-C relays being powered from Vin (using Grd next to Vin) and connected to GPIO 4 & 5 for signals.
2 x reed switches connected to the VIN and the GRD with a 10k pull up resistor each connected between the Vin and the switch with a signal coming off that connection to GPIO 15 & 2.

Code below but the error I have happens with most projects so I don't think its software related.

Code: Select all
#include <PubSubClient.h>
#include <ESP8266WiFi.h>
#include <ESP8266mDNS.h>
#include <WiFiUdp.h>
#include <ArduinoOTA.h>



const char* ssid = "*****";
const char* password = "*****";

// set pins for reed switches
const int OPEN_PIN = 15; // Pin connected to door open reed switch
const int CLOSED_PIN = 2; // Pin connected to door closed reed switch

//set MQQT broker credentials
char message_buff[100];
const char* MqttUsername = "*****";
const char* MqttPassword = "*****";
char* MqttServer = "192.168.1.166";
int Port = 1883;
char* subscribeTopic = "garage/door"; // subscribe to this topic; anything sent here will be passed into the messageReceived function

//create a telnet server for debugging
//const uint16_t aport = 8266;
//WiFiServer TelnetServer(aport);
//WiFiClient Telnet;

WiFiClient wifiClient;

//configure pins for relays used to trigger door switches
int relay1Pin = 5;
int relay2Pin = 4;

//call back routine to listen to incoming MQTT messages on subscribed topic
void callback(char* topic, byte* payload, unsigned int length) {
  int i = 0;

  Serial.println("Message arrived:  topic: " + String(topic));
  Serial.println("Length: " + String(length,DEC));
 
  //create character buffer with ending null terminator (string)
  for(i=0; i<length; i++) {
    message_buff[i] = payload[i];
  }
  message_buff[i] = '\0';
 
  String msgString = String(message_buff);
  Serial.println("Payload: " + msgString);

  // check contents of message and fire doors switch based on result
  if ((msgString.equals("ONE"))||(msgString.equals("one"))) {
    digitalWrite(relay1Pin, HIGH);
    Serial.println("High");
    delay(1000);
    digitalWrite(relay1Pin, LOW);
    Serial.println("Low");
  }else if ((msgString.equals("TWO"))||(msgString.equals("two"))){
    digitalWrite(relay2Pin, HIGH);
    Serial.println("High");
    delay(1000);
    digitalWrite(relay2Pin, LOW);
    Serial.println("Low");
  }else {
    Serial.println("Incorrectly formatted response");
    }
}

PubSubClient client(MqttServer, Port, callback, wifiClient);

int status = WL_IDLE_STATUS;
unsigned long lastSend;

void setup() {
  Serial.begin(115200);
  pinMode(relay1Pin,OUTPUT);
  pinMode(relay2Pin,OUTPUT);
  pinMode(OPEN_PIN, INPUT);
  pinMode(CLOSED_PIN, INPUT);
 
  Serial.println("Booting");
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  while (WiFi.waitForConnectResult() != WL_CONNECTED) {
    Serial.println("Connection Failed! Rebooting...");
    delay(5000);
    ESP.restart();
  }
  client.setServer(MqttServer, Port);
  lastSend = 0;
 
  // Port defaults to 8266
  // ArduinoOTA.setPort(8266);

  // Hostname defaults to esp8266-[ChipID]
  // ArduinoOTA.setHostname("myesp8266");

  // No authentication by default
  //ArduinoOTA.setPassword((const char *)"B@rb@d0s");

  ArduinoOTA.onStart([]() {
    Serial.println("Start");
  });
  ArduinoOTA.onEnd([]() {
    Serial.println("\nEnd");
  });
  ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
    Serial.printf("Progress: %u%%\r", (progress / (total / 100)));
  });
  ArduinoOTA.onError([](ota_error_t error) {
    Serial.printf("Error[%u]: ", error);
    if (error == OTA_AUTH_ERROR) Serial.println("Auth Failed");
    else if (error == OTA_BEGIN_ERROR) Serial.println("Begin Failed");
    else if (error == OTA_CONNECT_ERROR) Serial.println("Connect Failed");
    else if (error == OTA_RECEIVE_ERROR) Serial.println("Receive Failed");
    else if (error == OTA_END_ERROR) Serial.println("End Failed");
  });
  ArduinoOTA.begin();
  Serial.println("Ready");
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());
 
}

void loop() {
  ArduinoOTA.handle();
   if ( !client.connected() ) {
    reconnect();
  }

  if ( millis() - lastSend > 10000 ) { // Update and send only after 1 seconds
   getAndSendDoorStatus();
//   client.publish( "toledo/devices/name", (char*) String(ESP.getChipId()).c_str());
//   client.publish( "toledo/devices/ip", (char*) WiFi.localIP().toString().c_str());
//     printDebug("This is a telnet test");
   lastSend = millis();
  }
  client.loop();
}

void getAndSendDoorStatus(){
  String DoorState = "unknown";
  Serial.println("Collecting door data.");
  int DoorOpen = digitalRead(OPEN_PIN); // Read the state of the open switch
  int DoorClosed = digitalRead(CLOSED_PIN); // Read the state of the closed switch


  if (DoorOpen == LOW && DoorClosed == HIGH){
    Serial.println("Door is OPEN");
    DoorState = "OPEN";
  }
 
  else if (DoorOpen == HIGH && DoorClosed == LOW){
    Serial.println("Door is CLOSED");
    DoorState = "CLOSED";
  }
  else if (DoorOpen == LOW && DoorClosed == LOW){
    Serial.println("Something is wrong");
    DoorState = "Door Error";
  }
 
  if (DoorOpen == HIGH && DoorClosed == HIGH){
    Serial.println("Door in motion or part closed");
    DoorState = "Partially open";
  }
  client.publish( "garage/doorstate", (char*) DoorState.c_str());
}

void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    status = WiFi.status();
    if ( status != WL_CONNECTED) {
      WiFi.mode(WIFI_STA);
      WiFi.begin(ssid, password);
      while (WiFi.waitForConnectResult() != WL_CONNECTED) {
         delay(500);
         Serial.print(".");
      }
      Serial.println("Connected to AP");

     }
    Serial.print("Connecting to MQTT Server ...");
    // Attempt to connect (clientId, username, password)
    if ( client.connect("ESP8266 Device", MqttUsername, MqttPassword) ) {
      Serial.println( "[DONE]" );
      Serial.print("Subscribed to: ");
      Serial.println(subscribeTopic);
      client.subscribe(subscribeTopic);
    } else {
      Serial.print( "[FAILED] [ rc = " );
      Serial.print( client.state() );
      Serial.println( " : retrying in 5 seconds]" );
      // Wait 5 seconds before retrying
      delay( 5000 );
    }
  }
}

//void printDebug(const char* c){
////Prints to telnet if connected
//  Serial.println(c);
// 
//  if (Telnet && Telnet.connected()){
//    Telnet.println(c);
//  }
//}

void messageReceived(String topic, String payload, char * bytes, unsigned int length) {
  Serial.print("incoming: ");
  Serial.print(topic);
  Serial.print(" - ");
  Serial.print(payload);
  Serial.println();
}



Appreciate all input!

Cheers

Re: How and when to use VIN as a powersource for components

PostPosted: Thu Nov 16, 2017 6:34 pm
by rudy
2 x reed switches connected to the VIN and the GRD with a 10k pull up resistor each connected between the Vin and the switch with a signal coming off that connection to GPIO 15 & 2.


You can't do that. Your pull up resistor is fighting the pull down that is required to hold GPIO 15 low at startup. There is a 12K resistor to ground on GPIO 15 and it just barely meets the worst case voltage for a low condition in the CPU.

If you need to use GPIO 15 then you need to have the switch from Vcc (3.3 volts) to the pin. GPIO 0, 2 and 15 are lines that must not be exposed to noisy (long) lines. They are critical inputs for proper startup.

Re: How and when to use VIN as a powersource for components

PostPosted: Sun Nov 19, 2017 4:07 pm
by bigalboyo
philbowles wrote:Any reason your chose GPIO15 and 2 ? What results do you get if you use two different GPIO?


Honestly, I couldn't get the second reed switch to be read on any other pin so when I realised GPIO2 was also a TXD1, I put the second one on TXD2 and boom, it worked. Alas I don't know the significance of the TXD.

Re: How and when to use VIN as a powersource for components

PostPosted: Sun Nov 19, 2017 4:11 pm
by bigalboyo
rudy wrote:
2 x reed switches connected to the VIN and the GRD with a 10k pull up resistor each connected between the Vin and the switch with a signal coming off that connection to GPIO 15 & 2.


You can't do that. Your pull up resistor is fighting the pull down that is required to hold GPIO 15 low at startup. There is a 12K resistor to ground on GPIO 15 and it just barely meets the worst case voltage for a low condition in the CPU.

If you need to use GPIO 15 then you need to have the switch from Vcc (3.3 volts) to the pin. GPIO 0, 2 and 15 are lines that must not be exposed to noisy (long) lines. They are critical inputs for proper startup.


Well that explains the startup issues then! Thank you. My problem then though is that the reed switches only seem to be able to be read if they are on these TXD pins? Any idea why I can't get them to work on, for example, GPIO 12 & 14? (I've tried several GPIO but only the TXD ones seem to work).