D1 mini only can boot/upload with all sensers disabled

Moderators: grovkillen, Stuntteam, TD-er

Post Reply
Message
Author
Takzy
New user
Posts: 2
Joined: 12 Jul 2017, 13:57

D1 mini only can boot/upload with all sensers disabled

#1 Post by Takzy » 12 Jul 2017, 14:25

I have a question.

Somebody asked me to make a combination of an 8 channel relay, a 433 mhz transmitter and a D1 mini to let them control by website. Home automation.

Therefor i need all digital outputs D0 - D8, and i use D3 for the transmitter. The others (D0-D8 exccept D3) are all connected to the relay.

I have tested about five different D1's Mini, but all of them give the same behaviour:

- I cannot upload programs with the transmitter/relays attached (both of them must be disabled)
- I cannot use Serial.print and the plotter/monitor when the relays/transmitter are connected top the D1.
- I cannot boot the D1 mini with relays/transmitter attached. It only turns on the relay on D8.

A simple solution is to disconnect all attachments at startup. But it is no good solution: after a power-interrupt, you won't have to open the box and disconnect wires before you van use it again. And, after a power-distortion at night you won't something to start connected to the relay at D8.

Program:

Code: Select all

#include <ESP8266WiFi.h>
#include <RCSwitch.h>
 
const char* ssid = "ADD HERE YOUR SSD OF YOUR NETWORK";       // <<==This is your wifi SSID
const char* password = "ADD HERE THE PASSORD OF YOUR NERWORK";// <<==This is the password which belongs to the network with the SSID above
const String websitename = "Takzys control centre ";          // <<==This will be the title of the generated website

RCSwitch mySwitch = RCSwitch();
#define pinTX         0
#define pulseLength   308
#define bitLength     24
#define protocol      1

//Translation table for arduino clones (and D1's) with their ARDUINO port number used for the relays
//As D3 is used for 433 Mhz, the relay is in my case attached to D0 - D8, except D3
int pinTranslator[9] = {0, 16, 5, 4, 2, 14, 12, 13, 15};

//Device names are below in the (client.print) section where the HTML is generated. 
//The exact location can be found by searching for: "var desc = [" without quotes.
//This section matches the devices with their destination. So device 1 can be used with a relay, 
//or with a code for 433 mhz.
//Destinations: 1 - 8 = relay number 1 - 8, 11 - 18 = wireless device 1 - 8, 99 = not in use)
//Device number:   XX  01  02  03  04  05  06  07  08  09  10  11  12  13  14  15  16
int devices[17] = {99,  1,  2,  3,  4, 11, 12,  7, 13, 14, 15, 18, 99, 99, 99, 99, 99};

//The codes below are customisable, but keep in mind that these codes are representations of bits, including a command. 
//So not every code will work. Read them out with receivedemo_advanced, and put them below.
//All codes need to have the same protocol and bitlength.
//Codes:                  01        02        03        04        05       06       07       08               
int turnOnCodes[8] =  {12063919, 12063917, 12063915, 12063911, 3700175, 3700173, 3700171, 8429393};
int turnOffCodes[8] = {12063918, 12063916, 12063914, 12063910, 3700174, 3700172, 3700170, 8429393};

WiFiServer server(80);
 
void setup() {
  WiFi.begin(ssid, password);
 
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
  }
 
  // Start the server
  server.begin();
 
  // Turn al pins off (On Wemos D1 mini HIGH = OFF)
  for (int i=1; i<9; i++){
    pinMode(pinTranslator[i], OUTPUT);
    digitalWrite(pinTranslator[i], HIGH); 
  }

  // 433Mhz setup
  mySwitch.enableTransmit(pinTX);
  mySwitch.setPulseLength(pulseLength);
  mySwitch.setProtocol(protocol);
}
 
void loop() {
  // Wait for connection
  WiFiClient client = server.available();
  if (!client) {
    return;
  }

  while(!client.available()){
    delay(1);
  }
 
  // Detect the request
  String request = client.readStringUntil('\r');
  client.flush();
 
  // Match the request.
  // POST requests are generated by the website (jQuery/AJAX) to turn on/off devices without a reload. 
  // Therefor no website will be served during a POST request.
  if (request.substring(0,4) == "POST") {
    for (int i = 1; i < 17; i++){
      if ((request.indexOf("/s" + String(i) + "=0") != -1)){
        turnSwitch(i, 1); //Turn switch on
      }
       if ((request.indexOf("/s" + String(i) + "=1") != -1)){
        turnSwitch(i, 0); //Turn switch off
      }  
    }
  } else {
    // There is no POST request (i.e. there will be a GET request).
    // This is a page (re)load, so serve the entire website. 
    client.println("HTTP/1.1 200 OK");
    client.println("Content-Type: text/html");
    client.println(""); 
    client.println("<!DOCTYPE HTML>");
    client.println("<html lang=\"en\">");
    client.println("<head>");
    client.println("<script src=\"https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js\"></script>");
    client.println("<title>" + websitename + "</title>");
    client.println("</head>");
    client.println("<body>");
    client.println("<div id=\"c\">");
    client.println("<div id=\"h\">");
    client.println("<span class=\"t\">" + websitename + "</span>");
    client.println("</div>");
    client.println("<div id=\"nb\">");
    client.println("<div id=\"n1\" onclick=\"nst(1)\"><div id=\"i1\"></div></div>");
    client.println("<div id=\"n2\" onclick=\"nst(2)\"><div id=\"i2\"></div></div>");
    client.println("<div id=\"n3\" onclick=\"nst(3)\"><div id=\"i3\"></div></div>");
    client.println("<div id=\"n4\" onclick=\"nst(4)\"><div id=\"i4\"></div></div>");
    client.println("</div>");
    client.println("<div id=\"s1\"></div><div id=\"s2\"></div><div id=\"s3\"></div><div id=\"s4\"></div>");  
    client.println("</div>");
    client.println("</body>");
    client.println("<style>");
    delay(0);

    // Serve the embedded CSS code
    client.println("body{padding:0px;margin:0px;background-color:#000;font-family:Helvetica, Arial;}");
    client.println("div{height:140px;position:absolute;width:100%;}");
    client.println("#c{position:relative;min-width:640px;}");
    client.println("#h{background-color:#02426b;text-align:center;width:100%;}");
    client.println("#nb{top:140px;background-color:#02556b;}");
    client.println("#i1, #i2, #i3, #i4 {width:100px;height:100px;position:relative;margin:auto;}");
    client.println("#n1, #n2, #n3, #n4{top:0px;padding-top:20px;width:25%;}");
    client.println("#n1{left:0%}");
    client.println("#n2{left:25%}");
    client.println("#n3{left:50%}");
    client.println("#n4{left:75%}");
    client.println("#s1, #s2, #s3, #s4{top:280px;}");
    client.println(".bt{background:linear-gradient(#444, #000); background:-webkit-linear-gradient(#444, #000); vertical-align:middle;border:1px solid black;}");
    client.println(".d{color:#bbb;font-size:40px;margin:40px;float:left;position:relative;display:inline-block;}");
    client.println(".t{color:#fff;font-size:40px;margin-top:40px;position:relative;display:inline-block;}");
    client.println(".to, .tf{position:relative;width:100px;height:100px;float:right;margin:20px;}");
    client.println(".to{right:60px;}");
    client.println(".tf{right:40px;}");
    client.println("</style>");
    client.println("<script>");
    delay(0);

    // Serve the jQuery / Javascript.
    // There are the next functions:
    // additems  : Generates all devices and their two buttons (on and off).
    // nst       : Navbar set. Let the tabs work.
    // actresp   : Makes the website responsive, places two devices next to each other on bigger screens.
    // sendbutton: AJAX function to send url after buttonpress to server, without page-reload.
    // setimages : This will let the embedded SVG images in the right places.   
    //  Tip: open the source code in your browser to view the functions, there you can see them unescaped. 
    
    client.println("additems();nst(1);setimages();");
    client.println("window.onresize = function() {actresp();};");
    client.println("function actresp(){");
    client.println("for (i = 1; i < 10; i++) { ");
    client.println("for (j=1; j < 5; j++) {");
    client.println("if ($(\'#b\' + j + i).length != 0) {");
    client.println("$(\'#b\' + j + i).css(\'left\', ($(window).width() > 1280 ? ((i % 2) == 1 ? \'0%\' : \'50%\') : \'0px\'));");
    client.println("$(\'#b\' + j + i).css(\'width\', ($(window).width() > 1280 ? \'50%\' : \'100%\'));");
    client.println("$(\'#b\' + j + i).css(\'top\', ($(window).width() > 1280 ? (Math.floor((i - 1) / 2) * 150) + \'px\' : ((i - 1) * 150) + \'px\'));");
    client.println("}}}}");
    client.println("function nst(nr){");
    client.println("for (i = 1; i < 5; i++) { ");
    client.println("$(\'#n\' + i).css(\'backgroundColor\', (i == nr ? \'#4196e4\' : \'\'));");
    client.println("$(\'#s\' + i).css(\'visibility\', (i == nr ? \"visible\" : \"hidden\"));");
    client.println("}}");
    client.println("function sendbutton(nr, state){");
    client.println("var request = $.ajax({url: \"s\" + nr + \"=\" + state, method: \"POST\"});");
    client.println("}");
    client.println("function additems(){");
    delay(0);

    // On the next client.println line, the array of devices will be generated for the website. (ONLY for the website, make it match the pin <-> device list before the setup (almost at the top).
    // There are four tabs, and the devices must be placed in order of the tabs. To go the the next tab, add an escaped (!) "*"
    
    client.println("var desc = [\"TV\", \"Moodlight\", \"Window light\", \"TV light\", \"*\", \"Moodlight\", \"Readlight\", \"*\", \"Desk light\", \"Back windowlight\", \"Algemeen\", \"Table light\", \"*\", \"Voordeur\" ];");
    client.println("var descNum = desc.length; var sectNum = 1; var descNo = 1; var itemNo = 1;");
    client.println("for (i = 0; i < descNum; i++) {");
    client.println("if (desc[i] == \"*\"){sectNum ++; descNo = 1;} else {");
    client.println("$(\'#s\' + sectNum).append(\'<div class=\"bt\" id=\"b\' + (sectNum * 10 + descNo) + \'\"><span class=\"d\">\' + desc[i] + \'</span><span class=\"tf\" onclick=\"sendbutton(\' + itemNo + \', 0)\"></span><span class=\"to\" onclick=\"sendbutton(\' + itemNo + \', 1)\"></span></div>\');");
    client.println("descNo ++; itemNo ++;}}");
    client.println("actresp();}");

    //  Below is the javascript function setimages, with all six SVG images. They can be replaced by others, if wanted. 
    //  1. Create your own SVG images with Inkscape for example. Use 100 x 100 pixels as document size.
    //  2. Use less points, and snap to pixels. That keeps the file small.
    //  3. Export SVG, open in Notepad++
    //  4. Put everything AFTER the first <SVG ...> tag till the last </SVG> tag (so include only te close tag) below.
    //      (The opening tag is everywhere the same in this website, so it is written on the second rule below, and copied before every image)
    //  
    //  Notice that there is one image for the button, but javasript replaces the color red to black for the turn off one.
        
    client.println("function setimages(){");
    client.println("  var svgstart = \'<svg xmlns=\"http://www.w3.org/2000/svg\" height=\"100\" width=\"100\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\';");
    client.println("  var buttimg = svgstart + \'<defs><radialGradient id=\"b\" xlink:href=\"#a\" gradientUnits=\"userSpaceOnUse\" cy=\"80\" cx=\"60\" r=\"147\"><stop stop-color=\"#212121\" offset=\"0\"/><stop stop-color=\"#8a8a8a\" offset=\"1\"/></radialGradient><radialGradient id=\"a\" gradientUnits=\"userSpaceOnUse\" cy=\"80\" cx=\"20\" r=\"50\"><stop stop-color=\"#898989\" offset=\"0\"/><stop stop-color=\"#191919\" offset=\"1\"/></radialGradient></defs><g stroke-linecap=\"round\"><circle stroke-linejoin=\"round\" stroke-width=\".502\" stroke=\"#7e7e7e\" cy=\"50\" cx=\"50\" r=\"49\" fill=\"url(#a)\"/><circle stroke-linejoin=\"round\" stroke-width=\"1.25\" stroke=\"#000\" cy=\"50\" cx=\"50\" r=\"36\" fill=\"url(#b)\"/><path d=\"m50 35v19\" stroke=\"#ff0\" stroke-width=\"6.27\" fill=\"none\"/><path d=\"m61 40s8.07 7.32 3 17c-5.17 9.88-19.7 12.2-27 2-7-9.88 1-19 1-19\" stroke=\"#ff0\" stroke-width=\"6.27\" fill=\"none\"/></g></svg>\';");
    client.println("  $(\'#i1\').append(svgstart + \'<g fill-rule=\"evenodd\" fill=\"#fff\"><path d=\"m50 64c-0.943 0-2 1.06-2 2 0 0.943 1.06 2 2 2 0.943 0 2-1.06 2-2 0-0.943-1.06-2-2-2zm-41-45v43h81v-43zm-5-3c0-1 0-1 1-1h90c1 0 1 0 1 1v54c0 1 0 1-1 1h-90c-1 0-1 0-1-1z\"/><path d=\"m24 74s-2.49 2.59-2 4c1.42 4.1 8.26 5.52 11 6 3.12 0.541 11.3 1.11 17 1 5.97-0.119 13.9-0.893 17-1.4 2.29-0.375 10.1-2.43 11-6.6 0.264-1.17-2-3-2-3z\"/></g></svg>\');");
    client.println("  $(\'#i2\').append(svgstart + \'<path d=\"m2.9 23 45-13v16s-2-0.99-4-0.99c-2-0.000004-21 6.3-31 11-1.5 0.72-3 1.6-4 3-1.4 2-2 6.9-2 6.9l57 20 34-19v20s-1.6 4.2-3 5-2.6 0.67-4 0c-1.3-0.67-3-4-3-4l-20 13s0.17 3.5-0.38 5.1c-0.51 1.5-1.3 3-2.6 3.9-1.7 1.1-4.1 1.7-6 0.99-1.7-0.58-2.8-2.3-3.5-3.9-0.67-1.5-0.45-5-0.45-5l-42-19s0.25 1.8-0.99 3-4.9 2.8-6.9 2c-2.2-1-3.2-2-3.2-5z\" fill-rule=\"evenodd\" fill=\"#fff\"/><path d=\"m19 49 44 16 34-19s0.52-3.1 0.1-4.1c-0.54-1.3-1.7-2.5-3-3-9.9-4-22-7.3-32-8.1-2-0.16-6.1-0.17-8 0.3-12 2.8-22 6.5-32 13-0.8 0.48-1.5 1.2-2 2-0.55 0.89-0.99 3-0.99 3z\" fill-rule=\"evenodd\" fill=\"#fff\"/></svg>\');");
    client.println("  $(\'#i3\').append(svgstart + \'<g transform=\"translate(-67 -98) scale(.33 .33)\" fill-rule=\"evenodd\" fill=\"#fff\"><path d=\"m339 459c-4.96 2.64-8.57 5.64-9.29 14.9-0.719 9.26 5.54 21.6 10.9 32.7 5.39 11 5.59 25.6 5.59 25.6s-16.5-0.128-22.2-0.084c-5.1 0.047-10.7 0.92-10.9 8.36l-18 0.0215c-3.96 0.034-6.9 3.64-7.14 7.86l0.0449 8.57c43.1-0.13 90.1-0.0589 133 0l0.043-8.57c-0.239-4.21-3.18-7.82-7.14-7.86l-18-0.0215c-0.256-7.44-5.82-8.31-10.9-8.36-5.69-0.0445-22.2 0.084-22.2 0.084s0.201-14.6 5.59-25.6 11.6-23.4 10.9-32.7c-0.719-9.26-4.33-12.3-9.29-14.9-4.96-2.64-14.7-2.27-14.7-2.27-5.8-0.153-12.2 0.0283-16.4 2.27z\"/>  <path d=\"m263 448s-4.38 0.411-6.35-2.54c-1.96-2.95 0.274-8.89 0.274-8.89l38.6-91.8s0.977-2.31 2.14-3.21c2.67-2.06 6.16-1.91 6.16-1.91l100 0.126s4.07-0.455 6.74 1.21 4.51 6.65 4.51 6.65l38.1 89.2s2.29 5.58-0.491 8.93c-2.79 3.35-6.16 2.63-6.16 2.63z\"/> </g></svg>\');");
    client.println("  $(\'#i4\').append(svgstart + \'<path d=\"m28 51h3v-1h8v-1h-8v-1h-3zm3 40-5 5h48l-5-5zm-6-80h50v77h-50zm9 43h32v25h-32zm0-34h32v26h-32zm1 35v23.3l30-0.3v-23zm0-34v24h30v-24zm-17 67c1.84-0.0088 4.16 0.0088 6 0v-78h52v78h6v-84h-64z\" fill-rule=\"evenodd\" fill=\"#fff\"/></svg>\');");
    client.println("  $(\'.to\').css(\"background-image\", \'url(\"data:image/svg+xml;base64,\' + btoa(buttimg) + \'\")\');");
    client.println("  $(\'.tf\').css(\"background-image\", \'url(\"data:image/svg+xml;base64,\' + btoa(buttimg.replace(/#ff0/gi, \"#000\")) + \'\")\');");
    client.println("}");
    client.println("</script></html>");
    delay(0);  
  }
}

void turnSwitch(int switchnr, int state){
  if (devices[switchnr] < 10){
    //The device is controlled by relay
    digitalWrite(pinTranslator[devices[switchnr]], (state == 1 ? 1023 : 0));

  } else if (devices[switchnr] < 19){
    //The device is controlled by 433Mhz
    if (state == 0) {
      //Use turn on code on 433mhz
      mySwitch.send(turnOnCodes[devices[switchnr] - 11], bitLength);    
    } else {
      //Use turn off code on 433 mhz
      mySwitch.send(turnOffCodes[devices[switchnr] - 11], bitLength);
    }
  } 
}

Shardan
Normal user
Posts: 1156
Joined: 03 Sep 2016, 23:27
Location: Bielefeld / Germany

Re: D1 mini only can boot/upload with all sensers disabled

#2 Post by Shardan » 12 Jul 2017, 15:01

Hello,

some hints for going on (Even if this is a forum for ESPEasy firmware, not for ESP8266 in general ;) ).
The configuration you use will possibly run into troubles.

Some GPIO's need a specific setting, otherwise the ESP will not boot.
They are used to set the boot mode to "Boot from Flash" (starting from internal flash memory),
"Flashmode" (firmware flashing) and "SD-Card" (Starting software from external SD.)

The usual start mode for ESPEasy is "Boot from Flash". Therefore some GPIO have to be set:
D3/GPIO0 = 1 (high)
D4/GPIO2 = 1 (high)
D8/GPIO15 = 0 (low)

If your relay board or 433MHz device pulls one of these to a wrong settings the ESP will not boot.
For example, if your 433-transmitter has a pullup resistor on the data input, the D3 / GPIO0 will be pulled up and the ESP will boot into "Flashmode".

On the WeMOS the GPIO 9 and 10 are not broken out - they should be avoided anyways, they are used for SPI/SD-Card and well known for troubles.

I strongly recommend to use a PCF8574 GPIO multiplexer. It uses I²C (Usually D1 / D2 - GPIO 4 / 5 on the WeMos), it is easy to handle and
several PCF8574 can be connected together, giving a lot of GPIO pins.
The http commands to switch on/off are similiar to standard GPIO's - just "pcfgpio" instead of "gpio". I've made a 8ch relay driver this way, it works.

For Input you may set up one task per input pin for a PCF8574.

You may use one PCF8754 for driving your relays and use D5 - D7 (GPIO12,13,14) as additional direct input if necessary for what reason ever.

Regards
Shardan
Regards
Shardan

Takzy
New user
Posts: 2
Joined: 12 Jul 2017, 13:57

Re: D1 mini only can boot/upload with all sensers disabled

#3 Post by Takzy » 12 Jul 2017, 21:00

Shardan,

Excuse me, I see I took the wrong place for this question.

Besides that I want to thank you for your answer, it gives me enough ideas for a possible way to go. (The port extenders are ordered!)

Some tests show that disabling D1, D2 and D8 let it boot, and make it possible to upload programs again! I think I've used the wrong search terms for this problem, I've been looking for an answer for about two weeks now.

May i thank you?

Post Reply

Who is online

Users browsing this forum: No registered users and 38 guests