text:
Problem with html code in ESP8266 WebServer
Here I have a small problem:
I have an ESP8266, to which I have connected a matrix of LEDs to move text (the array of LEDs is made with the tape of LEDs addressable ws2812); when you turn on the computer you create an access point with a Captive Portal, which takes you to a small (though still ugly) web interface, where I can manage both the text I show and the speed, intensity and colors of it. All right, everything works ... I know I still have to change several things in the "code" html to work properly, but I hate CSS and right now it is functional.

The problem is the following:
I have several html forms that collect the values of the variables mentioned above (text to be displayed, color, brightness and speed with which the text is displayed), but every time I hit the "Send" button the browser (I have only tried the browser that comes with my phone (a Xiaomi Redmi Note 4, the application is called Browser itself) and the Google browser, on the same phone) takes me to a screen (I leave screenshot) where it shows me the html code of the page that resides within the esp8266 . And what bothers me is why !? Why does this happen!? (I leave a copy of the code too at the end!)

The only thing that occurs to me is that I am saving the page in a variable type String (String object, not an array of characters) ... will anyone know what is due?
Copy of the code:
//++++++++++++++++++++++++++++++++++++++++++++++//
//                LIBRERIAS                     //
//++++++++++++++++++++++++++++++++++++++++++++++//
        /*WiFi*/
#include <ESP8266WiFi.h>
#include <DNSServer.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>

        /*SSID and Password of your WiFi router*/
const byte DNS_PORT = 53;
IPAddress apIP(192, 168, 1, 1);
DNSServer dnsServer;
ESP8266WebServer server(80);
const char* ssid = "asd";
const char* password = "123456789";

String responseHTML = ""
  "<!DOCTYPE html><title>CaptivePortal</title>"
  "
Hello World!

This is a captive portal example. All requests will "
  "be redirected here.
";

//++++++++++++++++++++++++++++++++++++++++++++++//
//                  MATRIZ                      //
//++++++++++++++++++++++++++++++++++++++++++++++//
        /*LedStrip*/
#include <FastLED.h>
#include <LEDMatrix.h>
#include <LEDText.h>
#include <FontMatrise.h>

#define LED_PIN        2
#define COLOR_ORDER    GRB
#define CHIPSET        WS2812B
#define MATRIX_WIDTH   -8
#define MATRIX_HEIGHT  7
#define MATRIX_TYPE    HORIZONTAL_ZIGZAG_MATRIX

  /*Creando instancias de la matriz y el objeto*/
cLEDMatrix<MATRIX_WIDTH, MATRIX_HEIGHT, MATRIX_TYPE> leds;
cLEDText ScrollingMsg;

    /*Texto a mostrar y colores*/
char buf[200] = "HOME";
byte red = 255;
byte green = 255;
byte blue = 0;
byte intensity = 25;
byte intensity_old = 25;
int fastness = 300;

//++++++++++++++++++++++++++++++++++++++++++//
//                 Index                    //
//++++++++++++++++++++++++++++++++++++++++++//
String getPage(){
  String page = "<!DOCTYPE HTML>";
  page += "";
  page += "";
  page += "<meta name = \"viewport\" content = \"width = device-width, initial-scale = 1.0 maximum-scale = 1.0, user-scalable=0\">";
  page += "<title>Cartel Led</title>";
  page += "";
  page += "";
  page += "";
  page += "
Página de configuración del Cartel Led
";

  //Formulario para cartel
  page += "<FORM action=\"/\" method=\"post\">";
  page += "Introduzca texto a mostrar:
";
  page += "<input type=\"text\" name=\"texto\" id=\"texto\" value=\"Mickey\">";
  page += "
";
  page += "<input type=\"submit\" value=\"Enviar\">";
  page += "</form>";
  page += "
";
  page += "
";
  page += "
";

  page += "<FORM action=\"/\" method=\"post\">";
  page += "Elija el color:
";
  page += "<input type=\"range\" min=\"0\" max=\"255\" id=\"red\" name=\"red\" value=\"";
  page += red;
  page +="\" class=\"slider\">
";
  page += "<input type=\"range\" min=\"0\" max=\"255\" id=\"green\" name=\"green\" value=\"";
  page += green;
  page +="\" class=\"slider\">
";
  page += "<input type=\"range\" min=\"0\" max=\"255\" id=\"blue\" name=\"blue\" value=\"";
  page += blue;
  page +="\" class=\"slider\">
";
  page += "<input type=\"submit\" value=\"Enviar\">";
  page += "</form>";
  page += "
";
  page += "
";
  page += "
";

  page += "<FORM action=\"/\" method=\"post\">";
  page += "Elija la intensidad :
";
  page += "<input type=\"range\" min=\"10\" max=\"255\" id=\"intensity\" name=\"intensity\" value=\"";
  page += intensity;
  page +="\" class=\"slider\">
";
  page += "<input type=\"submit\" value=\"Enviar\">";
  page += "
";
  page += "
";
  page += "
";

  page += "<FORM action=\"/\" method=\"post\">";
  page += "Elija la rapidez:
";
  page += "<input type=\"range\" min=\"50\" max=\"1000\" id=\"fastness\" name=\"fastness\" value=\"";
  page += fastness;
  page +="\" class=\"slider\">
";
  page += "<input type=\"submit\" value=\"Enviar\">";
  page += "
";
  page += "
";
  page += "
";

  page += "";
  page += "";
  return page;
  }

//++++++++++++++++++++++++++++++++++++++++++//
//          REDIRECCIONAMIENTO             //
//++++++++++++++++++++++++++++++++++++++++++//
void handleNotFound(){
  server.send(200, "text/html", getPage());
}

//++++++++++++++++++++++++++++++++++++++++++//
//      handleSubmit                        //
//++++++++++++++++++++++++++++++++++++++++++//
void handleSubmit(){
  //Text to show
  if (server.hasArg("texto")){
      String texto_string = server.arg("texto");
      int texto_string_size = (texto_string.length()+1);
      texto_string.toCharArray(buf, texto_string_size);
      Serial.print("El texto a mostrar sera:");
      Serial.println(buf);
      }
  //Colors
  if (server.hasArg("red")){
      String red_h = server.arg("red");
      red = red_h.toInt();
      Serial.print("El color rojo cambio a:");
      Serial.println(red);
      }
   if (server.hasArg("green")){
      String green_h = server.arg("green");
      green = green_h.toInt();
      Serial.print("El color verde cambio a:");
      Serial.println(green);
      }
   if (server.hasArg("blue")){
      String blue_h = server.arg("blue");
      blue = blue_h.toInt();
      Serial.print("El color azul cambio a:");
      Serial.println(blue);
      }

  //Intensity
  if (server.hasArg("intensity")){
      String intensity_h = server.arg("intensity");
      intensity = intensity_h.toInt();
      Serial.print("La intensidad cambio a:");
      Serial.println(intensity);
      }

  //Fastness
  if (server.hasArg("fastness")){
      String fastness_h = server.arg("fastness");
      fastness = fastness_h.toInt();
      Serial.print("La intensidad cambio a:");
      Serial.println(fastness);
      }

  server.send(200, "text/plain", getPage());       //Response to the HTTP request
}

//++++++++++++++++++++++++++++++++++++++++++//
//            handleRoot                    //
//++++++++++++++++++++++++++++++++++++++++++//
void handleRoot() {
  if (server.args() ) {
    handleSubmit();
    } else {
      server.send(200, "text/html", getPage());
      }
}

//++++++++++++++++++++++++++++++++++++++++++++++//
//        Recoger del puerto serial             //
//++++++++++++++++++++++++++++++++++++++++++++++//
//int readline(int readch, char *buffer, int len) {
//    static int pos = 0;
//    int rpos;
//
//    if (readch > 0) {
//        switch (readch) {
//            case '\r': // Ignore CR
//                break;
//            case '\n': // Return on new-line
//                rpos = pos;
//                pos = 0;  // Reset position index ready for next time
//                return rpos;
//            default:
//                if (pos < len-2) {
//                    buffer[pos++] = readch;
//                    buffer[pos] = 0;
//                }
//        }
//    }
//    return 0;
//}

//++++++++++++++++++++++++++++++++++++++++++++++//
//            SETUP()                           //
//++++++++++++++++++++++++++++++++++++++++++++++//
void setup(){
  delay(1000);
  Serial.begin(115200);

  //WiFi initilization part
  Serial.print("Creating AP...");
  WiFi.mode(WIFI_AP);
  WiFi.softAPConfig(apIP, apIP, IPAddress(255, 255, 255, 0));
  WiFi.softAP("DNSServer CaptivePortal example");

  // if DNSServer is started with "*" for domain name, it will reply with
  // provided IP to all DNS request
  dnsServer.start(DNS_PORT, "*", apIP);

  IPAddress myIP = WiFi.softAPIP();
  Serial.print("AP IP address: ");
  Serial.println(myIP);
  server.on("/", handleRoot);
  server.onNotFound(handleNotFound);

  // if DNSServer is started with "*" for domain name, it will reply with
  // provided IP to all DNS request
  dnsServer.start(DNS_PORT, "*", apIP);

  server.begin();

  //LedStrip initialization part
  FastLED.addLeds<CHIPSET, LED_PIN, COLOR_ORDER>(leds[0], leds.Size());
  FastLED.setBrightness(intensity_old);
  FastLED.clear(true);
  delay(500);

  FastLED.showColor(CRGB::White);
  delay(500);
  FastLED.show();

  //Se declara la fuente que se utiliza
  ScrollingMsg.SetFont(MatriseFontData);
  //Se inicializa la matriz
  ScrollingMsg.Init(&leds, leds.Width(), ScrollingMsg.FontHeight() + 1, 0, 0);
//  ScrollingMsg.SetBackgroundMode(BACKGND_DIMMING, 50);
  //Se introduce el textoque se va a mostrar y su tamanho
//  ScrollingMsg.SetText((unsigned char *)TxtDemo, sizeof(TxtDemo) - 1);
  //Se declara los colores/efectos con los que se van a mostrar los mensajes
  ScrollingMsg.SetTextColrOptions(COLR_RGB | COLR_SINGLE, red, green, blue);

  //Para organizar el sentido del mensaje como mas convenga
  //Setear la direccion del mensaje
//  ScrollingMsg.SetScrollDirection(SCROLL_UP);
  //Setear la direccion de las letas
//  ScrollingMsg.SetTextDirection(CHAR_DOWN);

}

//++++++++++++++++++++++++++++++++++++++++++++++//
//              LOOP                            //
//++++++++++++++++++++++++++++++++++++++++++++++//
void loop(){
  dnsServer.processNextRequest();
  server.handleClient();         //Handling of incoming requests

  ScrollingMsg.SetTextColrOptions(COLR_RGB | COLR_SINGLE, red, green, blue);
  FastLED.setBrightness(intensity);

  if (ScrollingMsg.UpdateText() == -1) {
    ScrollingMsg.SetText((unsigned char *)buf, strlen(buf));}
  else {
    FastLED.show();
  delay(fastness);
        }

//  if (readline(Serial.read(), buf, 200) > 0) {
//        Serial.print("You entered: >");
//        Serial.print(buf);
//        Serial.println("<");
//    }

  delay(50);
}

You have content type "text/plain" in handleSubmit(). Use "text/html".

Hi! Thanks!!! I review this so many times!!! Thanks!!! Feel free to use this (punny) code if you want :D


text:
Reading text from SD card is returning weird characters
I have an ebook which is converted to a .txt file saved on an SD card, which is connected to the Arduino. I'm trying to display the words from the book on a 16x2 LCD display, one word at a time. It works mostly except when it reads a word that has an apostrophe or a pipe symbol: it does not display correctly to the LCD or the serial output.
For example the word "author's" will be displayed as "authorâs" (edit: there is actually two boxes between the "â" and the s that is not displaying on this forum) on both the LCD and serial output.
I've spent an entire day now with this one problem hopefully there is a mistake someone can pick up on :/
#include <LiquidCrystal.h>
#include <SPI.h>
#include <SD.h>

const int chipSelect = 53;

const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

char nextChar;
String wordBuffer = "";

void setup() {
  lcd.begin(16, 2);
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }
  Serial.print("Initializing SD card...");
  // see if the card is present and can be initialized:
  if (!SD.begin(chipSelect)) {
    Serial.println("Card failed, or not present");
    // don't do anything more:
    while (1);
  }
  Serial.println("card initialized.");
  // open the file. note that only one file can be open at a time,
  // so you have to close this one before opening another.
  File dataFile = SD.open("datalog.txt");
  if (dataFile) {
    while (dataFile.available()) {
      nextChar = dataFile.read();
      if (isWhitespace(nextChar)){
        lcd.print(wordBuffer);
        Serial.println(wordBuffer);
        lcd.display();
        delay(500);
        wordBuffer = "";
        lcd.clear();
      } else {
        wordBuffer = wordBuffer + nextChar;
        wordBuffer.trim();
      }
    }
    dataFile.close();
  } else {
    // if the file isn't open, pop up an error:
    Serial.println("error opening datalog.txt");
  }
}

void loop() {
}

When you look into the .txt file and look for that word and show the hexadecimal values for that word, can you see if that is normal ascii code or something else? You show the sketch, but I think the problem is the way the ebook is converted to a .txt file.

I checked the .txt file and it's in utf-8. I used calibre to save it as ascii but now in the text document a lot of letters have been replaced with question marks. Converting to ascii is not really going to work if things like apostrophes become question marks. maybe I can find a different format that will work.

The text file is not ASCII, it is UTF-8. You will either have to convert it to pure ASCII, or write (or obtain) a conversion routine to approximate the UTF-8 characters using ASCII on the Arduino.
Maybe this can help you.

source: Stack Exchange

license: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/

sort: votes


text:
Two HC05 Bluetooth Bind problem
I succeeded in giving an AT command. My two BL MAC addresses are 21, 13, A03B and 21, 13, A3E2.
When I want to connect one to the other I use AT+BIND=21,13,A3E2. But then I see Error(7). If I use another BL address from the Internet, it works.
So, why won't my 2 HC05 bind?

The solution is
AT+BIND=0021,13,00A03B

NB: Here I just added 00 left side and right side digits

I think that this is an error caused by a difference of firmware versions. Now BT is on version 3.0-20170601 and I think that this version does not accept these link or bind commands.

all_licenses: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/


text:
Potentiometer reading out letters
My potentiometer reads out t's or u's in my serial.
I believe that my potentiometer is wired correctly.
What am I missing?
Here is my code:
#include <VarSpeedServo.h>

VarSpeedServo servo;
const byte buttonLeft = 2;
const byte buttonRight = 3;
const int led = 7;
const int potentioPin = A0;
int potentioVal = 0;

void setup() {
  Serial.begin(9600);
  servo.attach(11);

  // PIN MODES
  pinMode(buttonLeft, INPUT);
  pinMode(buttonRight, INPUT);
  pinMode(led, OUTPUT);

  // INTERRUPT
  attachInterrupt(digitalPinToInterrupt(buttonLeft), turnServo, FALLING);
}

void loop() {
  int stateBtnLeft = digitalRead(buttonLeft);
  int stateBtnRight = digitalRead(buttonRight);

  if(stateBtnLeft == 0 && stateBtnRight == 0){
    digitalWrite(led, HIGH);
  } else {
    digitalWrite(led, LOW);
  }
}

void turnServo(){
  Serial.println("Button was pushed");
  potentioVal = analogRead(0);
  Serial.write("Servo moving with speed ");
  Serial.write(potentioVal);
  Serial.println("");
  //servo.write(180, potentioVal, true);
  //Serial.write("Reached position of motor");
  //lightLed();
}

void lightLed(){
  digitalWrite(led, HIGH);
  delay(2000);
  digitalWrite(led, LOW);
}

You need to use Serial.print instead of Serial.write.

write() is a function for binary data. I you want to print the number as text, use print() or println().
Serial.println(potentioVal);


text:
Is it possible to insert your own routine into the Reset procedure
I'm working with  ATmega328 NANO boards, and I would like to know if it is possible to INSERT my own routine, to be included in the things done during reset, BEFORE any pre-C initialization is done, or any upload of new code occurs. If this is possible, I'd like to know how. I'd want to be able to "install" this routine during setup(). I also would not expect it to work after a power loss. I'm talking about a reset caused by pressing the reset button, uploading code, opening a serial port, or any reset that was NOT caused by a loss of power.
I'm including a simple example sketch illustrating what I would LIKE to do, but it obviously won't do what I want as written, because I do not know the "magic" answer I'm seeking,
I've defined and initialized a global static byte outside of any functions. The setup() simply reads a byte from EEPROM and displays it with Serial.print(), and then stores its value in that global 'number'.  Now notice I created a void(void) function called magic(). It simply increments the global number and stores it in EEPROM. I call it "magic() because what I need to do to call it is unknown. I want some way to "install" magic() during setup(), so that it runs only as part of the reset process, before anything within code or data space is affected. By install, I don't mean just call the function. It should not actually be called unless RESET occurs.   Whatever "magic" has to be added to make this happen, the proof of the pudding will be that after loading the sketch. every time you press RESET, or even upload the sketch again, the printed number will be different, because it was incremented and saved when reset was pushed. NOTE: (I just edited some stupid errors here)
#include <EEPROM.h>

static uint8_t number =0;

void setup()
{
  uint8_t n = EEPROM.read(0);
  Serial.begin(57600);
  Serial.print(n);
  number = n;

  // somehow, install "magic" routine here

}

void loop() { }

void magic(void)
{
 ++number;
 EEPROM.write(0, &number);
}

why not at first line in setup()?

Yes, it is possible. See the documentation on memory
sections, from the avr-libc manual. For example:
// Run this after initializing the stack pointer and zero_reg, but
// before initializing the RAM.
void __attribute__((naked, used, section(".init3"))) magic(void)
{
    // Whatever...
}

Note that this runs after both a warm reset and a cold boot. See
Gerben's answer if you want to tell the difference between these two
reset conditions.
Note also that, if you just want some data to be preserved through a
reset, you can put it in the .noinit section, no need to use the EEPROM.

Edit 1: In response to the OP's comment, here is a small program
demonstrating the technique. It just quickly blinks the LED three times
early in the program initialization, then three more times, more slowly,
during setup():
#include <util/delay.h>

// Blink the LED three times, fast, early in the initialization.
void __attribute__((naked, used, section(".init3"))) magic(void)
{
    DDRB |= _BV(PB5);      // pin PB5 = digital 13 as output
    for (int i= 0; i < 6; i++) {
        PINB |= _BV(PB5);  // toggle PB5
        _delay_ms(100);
    }
}

// Blink the LED three times, slowly.
void setup()
{
    pinMode(13, OUTPUT);
    for (int i = 0; i < 6; i++) {
        delay(300);
        digitalWrite(13, !(i & 1));
    }
}

void loop(){}

I tested it on an Uno, and it works.
Note that magic() runs before the Arduino core library has been
initialized. At this point, many core function, like delay(), do not
work. Any job that is done here should be done low-level, using only
direct port access and avr-libc calls.
Edit 2: In the previous version of this answer I forgot the used
attribute. It worked with the old Arduino setup I tested with, but not
with the newest IDE. Adding the used attribute fixes this.

Well first... I edited my "wishlist" sketch a little, because i had some stupid errors (Forgot the Serial.begin and wasn't properly formatting the EEPROM calls. But unfortunately what you've suggested compiles, but doesn't work. If you try it with the editing my corrected sketch with your suggestion, you'll see it compiles, but won't work. The proof is that "255"  is always printed. I even tried substituting a short for() loop instead of the EEPROM write: "pinMode(13, OUTPUT);
for (int i= 0; i < 10; i++) {digitalWrite(13, i & 1); delay(20);}"  The LED doesn't flash when you press RESET.

@Randy: What I suggested does work. The Arduino core library doesn't if it has not been initialized. See my edited answer.

Hmmm... well I don't have any UNOs, only NANO boards. Doesn't work there. I do understand the wisdom of starting with a very low level and simple example. The only thing I changed in your edited code was to make the setup blink fast (300mS delay), and the magic() one 1000mS, so i wouldn't miss it. Also tried using different init levels. It compiles, but magic() has no pixie dust here so far. ;-) I'm sure this is the best advice I've gotten yet, and most likely to work. Can you think of why I'm not having any luck?

Why would "PINB |= _BV(PB5)" alternate the LED pin state?

@Randy because the datasheet says so in §18.2.2.

@Randy: My bad. I didn't notice that the current Arduino toolset now requires the used attribute for this to work. Edited the answer accordingly.

Eureka! But I'm still not sure. 1st, as it turns out, adding my EEPROM.write(0, ++number); to magic()  does work. I know because if I EEprom.read(0) and print it in setup(),   it will displays 1, not 255. The problem is when RESET is pressed, I'd hope to see it print '2', but instead it remains "1". If magic() really ran BEFORE data space was initialized, that would be the case. I also tried removing the "=0", and also removed the static keyword, which should move it to the 'bss' section. But the sketch still prints always '1'. So magic() runs before setup(), but not before memory clear.

And I might add, the reason I want to save to EEPROM on RESET, is because I want to also survive a code change (or code improvement in a big project). I normally save this way on loss of power, with an electric circuit that lets me know well in advance of the AVR losing power, and since that works I can pretty easily just turn off my power switch, then turn it back on and upload my code change. But if I can also save to EEPROM on reset, that will be a major bonus in some projects.

@Randy: I tested the code in your question with no modification other than the added attributes. This time I tested with the IDE version 1.8.5. Repeatedly pressing RESET, it prints "207208209210211212..." as expected. Also, note that magic() runs before the memory is initialized but after the bootloader, which can itself clobber some of your RAM, thus defeating your purpose. You may have to write a custom bootloader to be safe...

Well for me its printing the same value of "1" over and over again, and upgrading to 1.8.5 made no difference. I also see that if I change its initial value of 'number' to 1 instead of 0, the same code prints 129 repeatedly!. So I guess this just doesn't work with the NANO, and in any case is not reliable. And really, if magic() is going to run AFTER after "bootloader",  then the docs are lying to us.and,that pretty much brings me back to square 1. Would be nice if they actually gave us a true init0 that happened before ANYTHING when you press RESET. Guess not.

I'd like to at least experiment with "noinit" section, as I've been told elsewhere that trying to use a high level EEPROM.write() , like my example) won't work.. But now I don't think my NANO boards respect ANY rules! I made a simple sketch with byte attribute((naked, used, section (".noinit"))) number; Then my setup() does nothing but Serial.begin(57600); and Serial.println(number++); It compiles, but pressing reset always results in '0' being printed. If 'number' were not being initialized, and power isn't lost, I'd expect number (whatever it's value) to be +1 each run. No luck. :-(

@Randy: 1. “naked” is an attribute for code, “noinit” is for data. It doesn't make sense to mix them. 2. “noinit” means the data will not be overwritten by the startup code of the C runtime, but it doesn't prevent the bootloader from writing into that part of the RAM: the bootloader knows nothing about your sketch.

@EdgarBonet OK... that's helpful. But still..can you explain this?  Simple sketch... start with a line saying "byte number attribute((used, section (".noinit"))) ; Then, setup() just Serial.print()'s the number, and then increments it. Thats all. So whatever 'number' starts out as, if I press the reset button, the sketch should print one greater than that last time. That simply doesn't happen for me... the same number (usually zero) is printed over and over. I can't easily post a whole sketch in a comment, but am I doing something wrong? Or is "noinit" lying?

@Randy: Works for me on an Uno. Presumably the bootloader of the Nano uses more RAM than the Uno's optiboot. In my test, number was stored at 0x01c3, past the Serial object, its vtable, its buffers, and the core's timekeeping variables. You will have to experiment to know what addresses your bootloader overwrites.

@EdgarBone Thanks... you've confirmed what I've been suspecting, which is that the boot loader code in my nanos is not up to date. I see a lot of folks re-programming NANOs with the OPTI-BOOT, which is for the UNO, but you can use it with the NANO, and use a define to make sure all the upper analog input pins are configured. I have to either build or buy a programmer. easy to build, but they are so cheap. I'll bet the code works on my NANO with a more up to date bootloader. Thanks again.

You can check the MCUSR register to see the cause of the reset. In your case you could use:
if( bit_is_set(MCUSR, EXTRF) )// reset button was pressed
{
    MCUSR = 0;// clear the reset-flag

    // "magic" routine here

}

Thanks. I understand this, but I don't care what caused the reset.

Are you kidding me. You specifically said reset and “NOT by loss of power”. Well; now I don’t care anymore

I think its obvious what i meant: I wanted it to WORK when a RESET occurs, but I don't expect it work if there is a loss of power.

It was so obvious that you have two people giving you an answer to the wrong interpretation of that part of the question!

If you use the latest version (7.0, July 2018) of Optiboot, you can use the MCUSR register to check the reset cause.
You need to use the latest version because previous versions of the bootloader cleared the MCUSR before starting the sketch (as recommended in §15.9.1 of the ATmega328P datasheet). This was changed in version 7.0 (a50f47b).
#include <EEPROM.h>

static uint8_t ch = MCUSR;

void setup() {
  MCUSR = 0;
  uint8_t n = EEPROM.read(0);
  Serial.begin(115200);
  Serial.print(n);
  if ((_BV(PORF) & ch) == 0) // not a power on reset
    magic(n);
}

void loop() { }

void magic(uint8_t &number) {
   EEPROM.put(0, ++number);
}

Thats interesting, but I've seen this before, and I don't really care what caused the reset. what I do want, and hope I explained, is for the routine I called magic() to run when a reset occurs, before any new sketch code is loaded, or before any pre-C cleanup or initialization of memory/variables occur.

@Randy You specifically asked: "I'm talking about a reset caused by pressing the reset button, uploading code, opening a serial port, or any reset that was NOT caused by a loss of power." What is the reason you need it to happen before the C initializations?

I'll answer, but I don't want to side track too much into why. In a complex system, I usually put everything important into a structure (states, timers, etc.), and save it all to EEprom before turning it off. The 1st thing the code does when it starts is read the struct back out of EEprom, so it can resume in the exact same state. It would be nice if uploading a code change could first trigger my save routine too. I can find a way to do the save manually first, but it would be nice to automate it. Sadly, nothing I've tried has worked. Not even the .init sections.

@Randy That doesn't make any sense to me: when the upload is started, the MCU resets, so your configuration (states, timers) are reset and lost.

Again, the ultimate goal is to save date to EEPROM. I can assure you that saving a structure, containing all your states and timers to EEPROM, does provide a solid and reliable recovery to exactly where your program "left off", if the first thing you do is recover your structure from the EEprom where you saved to.

@Randy Yes, of course, but it doesn't matter when you read back the EEPROM config, you could do it in the setup. But if you want to save the current, unsaved state before updating, you cannot do that after a reset.

apparently not, but if there were a way to steal the RESET vector as I'd hoped, it definitely would be possible to save data to EEPROM on RESET, as long as it wasn't a power up reset.


text:
Arduino SD card cannot write (writes crap files and then I get error)
I am developing a very simple project to measure some temperatures and store them in an SD card. I have a problem trying to write. No matter what I do the SD card always ends up with content like this:

And in read only mode. I have formatted it in FAT16, FAT32, in Windows an Ubuntu and always the same. I have changed between two different Arduino UNO boards, two different SD modules connected like this:

and extremly simple codes like this example and I always get the same.
Detailed example of what I do and what I get
I have wrote this simple code to test:
#include <SD.h>
#define CHIP_SELECT_PIN 10
/* CIRCUITO ----------------
* SD card attached to SPI bus as follows:
* MOSI - pin 11
* MISO - pin 12
* CLK - pin 13
* CS - pin 10. */
File archivo;
char cadena[20];
char c;
void setup(void) {
Serial.begin(9600);
while (!Serial) {;} // Esperar a que se inicialice la comunicacion serial
      while (Serial.read() >= 0) {;} // Limpiar el buffer
// INICIALIZAR LA MEMORIA ----------------------------------------
Serial.print("Initializing SD card... ");
pinMode(CHIP_SELECT_PIN, OUTPUT);
if (!SD.begin(CHIP_SELECT_PIN)) {
  Serial.println("Unable to initialize. Remove the card.");
  while (1);
}
Serial.println("OK!");
// ABRIR UN ARCHIVO PARA ESCRIBIR --------------------------------
if (SD.exists("ARCHIVO.TXT")) {
  Serial.println("Deleting existing file with the same name. ");
  SD.remove("ARCHIVO.TXT");
}
Serial.print("Creating new file... ");
if (!(archivo = SD.open("ARCHIVO.TXT", FILE_WRITE))) {
  Serial.println("Unable to create the file. Remove the card.");
  while (1);
}
Serial.println("File successfully created. ");
Serial.print("Send a string to store in the card... ");
while (Serial.available() == 0); // Nos quedamos esperando a que nos manden el numero
leerCadena('\n', cadena, 19);
Serial.print("The following string was received: \" ");
Serial.print(cadena);
Serial.println("\"");
archivo.print(cadena);
archivo.close();
Serial.println("The string was successfully stored in the card. ");
// Lectura de los datos guardados en la memoria ------------
Serial.print("Preparing to read data in card... ");
if (!(archivo = SD.open("ARCHIVO.TXT", FILE_READ))) {
  Serial.println("Cannot open file to read. Remove the card. ");
  while(1);
}
Serial.print("The string stored in memory is: \"");
while ((c = archivo.read()) >= 0) {
  Serial.print(c);
}
Serial.println("\"");
archivo.close();
Serial.println("Remove the card.");
while(1);
}
void loop(void) {}
void leerCadena (char corte, char* cadena, byte n_bytes) {
  byte n_leidos;
  n_leidos = Serial.readBytesUntil(corte, cadena, n_bytes);
  cadena[n_leidos] = '\0';
  delay(100);
  while (Serial.read() >= 0) {;}
}

and what I am doing and getting is:

First I format my SD card in FAT32 using Gparted (the same happens if I format it in FAT16 or 32 both in Ubuntu and Windows).
I test the SD card in my computer.  It works perfectly. I can remove it and plug it again and the data is there. Everything OK.
I put the card in the SD slot connected to Arduino and run the above program. What I get through the serial monitor is
Now I remove the card from Arduino and insert it into my computer. This is its content:  The file "readme.txt" contains the same text as before. The file "ARCHIVO.TXT" is empty. The binary files vary in size, e.g. the second one is 3 GB and fourth one is 774 MB.
Now I try to modify the content in "readme.txt" and I get this:  I cannot delete files either.
I remove the SD card from my computer and insert it again into Ardino. Reset the board and through the serial port I get:
Now the content of the card seen in the computer is different:  and the file "ARCHIVO.TXT" is not present.
If I put the card again in Arduino and reset the board everything repeats from step number 3. I mean, it creates the file "ARCHIVO.TXT" among with the other strange files, in the next time I put it into Arduino it deletes the file "ARCHIVO.txt", and so on.

If after all this I format the SD card in my computer, we are back in step number 1.
I am about giving up with Arduino and the SD module and go to a Raspberry. But it is much more expensive for this extremly simple task I need to do...

The problem was magically solved. I think the cables were the causing this issue. I was using cables of about 15 cm, now changed them to 5 cm and is working perfectly.

-Did you change the CS pin in the code to 10?
-It can be a problem with the SD card, try another and tell us.
-After the "dataFile.close();" put: "if(dataFile)Serial.println("not closed");" and watch the serial monitor window.

Thanks for your answers. I have tried almost everything. I have added more information to the question. I am waiting for a new SD card. After that I run out of ideas about what could be the problem...

You have to guarantee that the file.txt is not opened before you shutdown the power or take the SD card off. I recomend you firstly, to do a "for" loop to stop in "X" iterations. If it works, you can put then a push-button in your project to stop any time.

I had the same problem (using a UNO with the MH-SD module directly connected to the arduino). The module apparently correctly initialised and I could list the files that were already there but when I attempted to create a single blank file ready for reading, a whole bunch of random named files were created many of which were enormous (according to my PC, although it said they all corrupted and couldn't open any of them). And then the card wasn't recognised when I tried using it again and had to be reformatted. I eventually found that one of the wires I was using, specifically the one to GND adjacent to MISO, was faulty. I suspect the length of the cables is irrelevant, I think that user171780 had a faulty cable in the same position.

I change voltage from 5V to 3.3V and move GND to the GND pin near the 3.3V. Now I can write and read a text file on a SD card.

I think maybe the problem comes from the SD module you use. I have used the SD module just like you.And I can not write or read data successfully. More seriousely, my card broken and the damage is permanent.This connect is the new SD module I use, and I use successfully. You can dry by yourself.
https://www.qutaojiao.com/8515.html?fbclid=IwAR0T9dFoAOyJhTCSOHeDWQTE_Iuq8l5eGN9ByYth2uPmIyzC2bHLdt0_cKk

This is essentially a "link only" answer (and to a foreign language site). You should provide the (translated, English) important parts of the answer directly here, not link to them.


text:
Local char* - keeps its value
Sorry for novice question in Arduino, but I'm trying to figure out why res is keeping its value when up_cmd0 is being called again.
for example - if num=8 in first run and the result is :up_cmd0_res: 8, and second run num=12, the result is: up_cmd0_res: 812
void up_cmd0(){
  char num[8];
  char *res = "up_cmd0_res:";
  itoa(counter2, num, 10);
  strcat(res ,num);
  client.publish(inTopic,res);

char *res = "up_cmd0_res:";

In principle, res should be a const char *. Const because it is
pointing to a literal string, and you cannot (ar at least, you are not
supposed to) change a literal string. The compiler should warn you on
that... if you enable compiler warnings.

strcat(res ,num);

This is very wrong. strcat() expects as its first argument an pointer
to a modifyable array large enough for the resulting concatenation
(and the terminating \0). In other words, you have to allocate enough
room for the whole string, then fill the beginning of the allocated
array with the first substring, then only call strcat():
char res[24];
strcpy(res, "up_cmd0_res:");
strcat(res, num);

What happened is that you initially had, in memory, something like this:
<----- memory reserved for the string literal ---->
'u' 'p' '_' 'c' 'm' 'd' '0' '_' 'r' 'e' 's' ':' NUL
 ^-- res

On the first call to stracat(), you overwrite the terminating NUL and
end up with
<----- memory reserved for the string literal ---->
'u' 'p' '_' 'c' 'm' 'd' '0' '_' 'r' 'e' 's' ':' '8' NUL
 ^-- res

Note that the new terminating NUL is now occupying a byte in memory that
hasn't been allocated for this purpose. You have likely overwritten some
global variable. Next time you call strcat(), you again replace the
terminating NUL and continue to overwrite whatever happens to be stored
in this part of the RAM. Expect a crash or program misbehavior.

thank you for your answer- can you please explain in what cases should I use char* instead of char ? and why def of res at the begining of the code as a predefined value- at the begining of function does not override is value ?

@Guy.D: 1. Re char* vs char[]: that's not a simple topic, but it's thoroughly covered in the section Arrays and Pointers of the C FAQ. Read it: it has in one place the answers to all the questions you are asking here. 2. Re def of res does not override is value: res is not a string, it's defined as an address and initialized at the beginning of the function to the place in RAM where the compiler stored the anonymous string literal. See also the other answers.

Only the pointer, *res, is a local variable. The string "up_cmd0_res:" itself is elsewhere in RAM, stored as a literal and not meant to be modified.
Your strcat() call overwrites (extends) the literal each time you call it - which, by the way means that the growing string will be overwriting something else - whatever was following the string literal in global memory!!
You need to provide a character buffer within your function, large enough to hold "up_cmd0_res:" plus the longest thing you might ever append to it, plus one more byte for the zero-terminator. That buffer should be re-initialized on every function entry, before you append anything to it. Then make the strcat call to append to it. (These two calls will each manage the terminator for you).
The fact that this program didn't crash (or did it?) is only just by happenstance. If you call this function as it is initially written, enough times, your string literal will grow until it overwrites something important and either produces incorrect results (by over-writing some other data, or crashes (by overwriting the stack, especially the current function's return-address).

no. it did not crash

It will, in time.

It is incorrect to strcat into a field pointing to a literal. The code below is shorter, easier to understand, and does not corrupt memory:
 char res [20];
 sprintf (res, "up_cmd0_res:%i", counter2);
 client.publish(inTopic,res);

The field res needs to be long enough to hold the literal string (which is not modified doing it this way) plus the number you are adding to the end, and a terminating 0x00 byte.

can you please explain what "literal" is?

OK. A literal is when you literally put a string into a variable. For example:
char *res = "up_cmd0_res:";

So res isn't pointing to some variable, it is pointing to a literal string in the code. Now check this out:
void setup() {
  Serial.begin (115200);
  char * a = "foo";
  Serial.println (a);
  strcpy (a, "bar");
  Serial.println (a);
  char * b = "foo";
  Serial.println (b);
}

void loop()
{
}

Are you expecting this code to print:
foo
bar
foo

It should, right?, because the variable b contains "foo".
However it actually prints:
foo
bar
bar

This is because the strcpy has modified a literal string ("foo") to now contain "bar". The compiler is smart enough to think that every time it sees "foo" in the code it can place a single piece of memory with "foo" in it, because it is a literal (and literals don't change). But now you have modified that.
The compiler does give a warning:
/tmp/arduino_modified_sketch_905830/sketch_aug19a.ino:7:12: warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]
 char * b = "foo";
            ^

Imagine if you were able to change the literal 5 so that every time you added 5 to something it actually added 42? That wouldn't be so great, right?

Your code was worse than that, because you didn't just replace a string with something the same length, you used strcat which replaces it with something longer.

thank you for your answer. can you please explain what "literal" is ?

Because you're changing a string literal. These literals are in static memory, so they persist between function calls.
On top of that, changing them results in undefined behaviour.
You're also writing out of the bounds of the string.
My recommendation:
void up_cmd0(){
  const size_t int_max_digits = floor(log10(pow(2, 8 * sizeof(int) - 1))) + 1;
  char num[int_max_digits + 2]; // max digits + minus sign + null terminator
  const char *str = "up_cmd0_res:";
  char buffer[strlen(str) + sizeof(num)] = {};
  strcat(buffer, str);
  itoa(counter2, num, 10);
  strcat(buffer, num);
  // ...
}

You shouldn't be using globals to get values from one function to the other (counter2), try to pass it as a parameter to the function.


text:
How can I power a NeoPixel ring and strip through Arduino MKR1000?
I currently have a MKR1000 which is connected to 1 ring with 8 neopixels, 1 strip with 20 neopixels, 1 microwave sensor, 1 speaker, 1 rotary encoder. I am running the NeoPixel positive and negatives through a 220 µF capacitor, and the data pins through 220 Ω resistor.
I am soldering these components onto a board, but currently, when I plug the MKR1000 into my USB it says it's drawing too much power, the Arduino also smokes and I can smell burning, so disconnected straight away.
What am I doing wrong?

A schematic diagram would help the understanding your setup

The on-board regulator of an Arduino can supply a maximum of 500 mA when connected to USB, and up to 1000 mA when connected to an external power supply (see Maximum current from Arduino 5V power pins).
If your components are drawing more current than that, then you will need to use an additional separate power supply for the NeoPixel ring - ensuring that the ground lines of the Arduino's supply and the NeoPixel's supply  are connected.
If the Arduino has been smoking then it may already be damaged. Did you see which part was smoking? If it was a capacitor as shown in Is my Arduino dead?, then this answer may help.


text:
Looking for light-weight Arduino OLED library that supports text and bitmaps
I'm trying to incorporate a screen into my Arduino code which is quite large already. The Adafruit SSD1306 library is overly large and has a lot of unnecessary things in it. I've found the SSD1306Ascii library which is great because it takes up barely any space, but I really would like to be able to display a bitmap logo on the screen. Does anyone know of a library that is light weight but still supports bitmaps?
Thanks.

Light-weight with bitmaps and your sketch is already large? Then need a newer Arduino board, for example one of the mkr series. Do you know these: https://github.com/olikraus The u8g2 library is large, and the 8x8 option has no bitmaps. The older U8glib is memory efficient but it is still large and it takes time to learn how to use it (because it is memory efficient it has a specific way to update the screen). What is so large about your sketch? Are you a beginner with programming? In the end you need another arduino board anyway, so it is easier to move to a new arduino board right now.

This is supposed to be a small implementation. https://github.com/nicoud/Oled
I have not used it, but it does look interesting. You can pick the bits that you need.
https://www.didel.com/OledLib.pdf


text:
esp8266 and arduino pro mini
I have few sensors. Temperature sensor (DHT22), flow rate sensor, rpm optical tachometer sensor and a rgb led.
I want to use adafruit IO to get values of these sensors and change the colour of the led.  Most of the tutorials online use a builtin WiFi module  but I want to do it separately. please guide me how to do it?
I am going to use esp8266 and  arduino nano.

Please read [ask] and How to ask a good question for Arduino Stack Exchange and then edit your question to suit.

Use tutorial for the esp8266 module to connect to Adafruit IO (MQTT). Then code the exchange of the data between Nano and esp8266 using Serial communication.
(You can test the Serial communication by sending lines to esp8266 from Serial Monitor and of course by showing the prints from the Nano.)
Consider using only esp8266 dev board like Wemos D1 mini or NodeMCU.

Why would you recommend using Wemos or NodeMCU ?

@Guy.D, instead of Nano+esp8266, only a esp8266 dev board


text:
How should you predict the battery size required for a project?
I am using an Arduino nano along with an ESP8266.  The nano is connected to an OLED display and a keypad. The ESP8266 uploads the data entered from the keypad onto a server. I wish to make the device portable; i.e. add a battery to it so that it can last for at least 8 hours.
How can I calculate the rating for the LiPo battery to use? I understand that it is very important to know the current rating of the devices in use.
How can I make an approximate guess?

You don’t guess, you measure. Use a multimeter to get a rough indication. Make sure you measure different states of your program. For example, sending data uses more power

if you want to save power, get rid of the nano; the esp can run a screen and keypad directly...

I do not possess some of the components with me presently so how can I ?

Yes, you need to know the average current draw over the period of an hour (or over a period that you then extrapolate to an hour).  That is the mAh (milliamps per hour) that your circuit draws.
It can be hard to calculate the actual current, though, since it is always changing depending on what is actually happening in your system at the time.  So I would suggest picking up a cheap current monitoring USB dongle from eBay / Amazon / Wherever (one with an LCD screen that gives mAh, such as this one and use that to get the total mAh of your system over an hour.
Multiply that mAh by 8 (the number of hours you want it to run for), and that will give you the minimum mAh for your battery. And then add some more as a safety margin, since the capacity of a battery is subject to many things (like temperature, age, etc), and the rated value is only a rough guide.
For instance, if you find your circuit uses on average 387mAh, then a battery of 3600mAh should be adequate.

You should probably have them factor in how long they want the project to remain on while using battery power, instead of just multiplying by 8. I’ve had projects that only consumed 120mAh but had a 12000mAh battery because it needed to last a very long time without charging.

The "8" is how long the want it to stay on battery. " wish to make the device portable, i.e. add a battery to it so that it can last for at least 8 hours."

Your wording in the answer made it seem that 8 was an arbitrary rule-of-thumb, IMHO

Does that read better for you?

Much better. I know when I was learning omissions like that confused me.

Current consumption is measured in Amperes, battery capacity in specified in Amperes per hour.

So if a device is rated 5V/2A then does it mean that it draws 2A in one hour or 2A instantaneously?


text:
Repair Arduino with too much voltage exposure
I have used the 5V pin instead of the Vcc pin to operate some sensors on the Arduino MKR GSM 1400. Altough the operating voltage is 3.3V.Because of that it doesn't work properly anymore, some analog sensor values are clearly wrong and the GSM module works only occasionally. Is there any way to repair this myself or send is somewhere, or should I buy a new one?

some analog sensor values are clearly wrong ... are you sure? .... you gave inadequate information

Unless you tell exactly what you did, it’s hard to say which part might have been damaged. Connecting 5V to some external sensor in itself isn’t a problem.

I put 5V into an input pin. But only 3.3v are allowed

Buy a new one. Anywhere willing to repair such a thing would probably charge 10x the value of the product in time alone.

Feeding 5 volts into an input most likely cause the protection diode on that input to conduct the 5 volts onto the 3.3 volt supply. That in turn would exceed the voltage on all the 3.3 volt connected parts. Likely to cause more damage than just to the affected input.
The cost of shipping and labour to repair the board would exceed the cost of buying a new replacement board. A repair would require too many parts to be replace. And replacement would be required of even parts that might appear to work because the risk of failure would be high.
Buy a new board and be confident that it will work.


text:
data integrity when interrupts are too fast
I have an encoder that fires ~54000 interruptions per second.
This is way too fast for my arduino uno.
But I'm trying to see what I can get from it anyway. For science.
unsigned long tickACount = 0;
unsigned long tickBCount = 0;

void myInterrupt(){
  tickACount++;
  tickBCount++;
}

Then in my main loop, every second I print tickACount and tickBCount.
I can see my arduino is able to handle only about 2050 interrupts per second. No surprise here.
What surprises me, is that tickACount and tickBCount have different values! tickBCount is consistently higher that tickACount.
Ok now I switch them to volatile. And according to the documentation, volatile only makes sense for 8bit values. The counts will eventually overflow but it doesn't really matter. I just want to see if those two variables are still different.
volatile uint8 tickACount = 0;
volatile uint8 tickBCount = 0;

void myInterrupt(){
  tickACount++;
  tickBCount++;
}

The result is that the two values are still different.
Also, wrapping them into some ATOMIC macro does not help.
From what I read, interrupts cannot be interrupted.
And beside, if my interrupt was aborted midway, then tickACount would be higher than tickBCount, not the other way around.
Therefore, what can be the explanation for those two variables to be different?
Thank you for any idea!

They are the same. But when you print one and then print the other one, there has been interrupts between that. Make a full sketch that shows the problem. With a lot optimizations, the uno board might do more than 54kHz interrupts, perhaps 100kHz. Interrupt tutorial: https://gammon.com.au/interrupts

You can save quite a few CPU cycles by creating your own ISR instead of relying on the one from the Arduino core to call your interrupt handler. See this answer, section Write your own ISR.

If you want simple counter, why don't you use Timer1 or Timer2 with external clock source?

Would you consider using extra hardware to reduce microcontroller load?  How about using shift registers to count pulses.

I was convinced that 54kHz is way to fast for Arduino, which runs at 16MHz. That's only ~300 cycles per interruption + it has to handle the normal loop.
I replaced my interrupts by the Encoder library https://github.com/PaulStoffregen/Encoder, and it now seem to work fine. I digged a bit into that library, it seems to do about the same thing as I did, but in assembly with probably some big optimization done.
Well done, about the tickCountB > tickCountA. The possibility of tickCountB being incremented during the 2 prints hasn't come to my mind. I guess that's experience!

54000 interruptions per second [...] is way too fast for my arduino
  uno

Your test is probably flawed. My Uno does handle that interrupt rate
with no issues. See my test code below.

my arduino is able to handle only about 2050 interrupts per second

You are probably doing something wrong, like blocking interrupts for too
long, or using a library that does so.

What surprises me, is that tickACount and tickBCount have
  different values!

As previously stated in comments, this is not the case. Instead, the
counters have been incremented while you were printing them.

And according to the documentation, volatile only makes sense for 8bit
  values.

Either the documentation is grossly wrong, or (most likely) you have
misread it.

From what I read, interrupts cannot be interrupted.

This is indeed the default behavior. You could change it, by issuing
interrupts() within the interrupt handler, or by declaring an ISR as
ISR(XXX_vect, ISR_NOBLOCK)
{
    ...
}

but that is seldom done.
Below is my test code. I used Timer 2 to generate a square wave on
pin 3, which is both a PWM pin (OC2B) and an interrupt pin (INT1).
The PWM frequency is about 54.054 kHz.
const uint32_t PRINT_PERIOD = 1e6;  // print counts every second

struct TickCounts {
    uint32_t tickA;
    uint32_t tickB;
};

volatile TickCounts rawCounts;

void myInterrupt() {
    rawCounts.tickA++;
    rawCounts.tickB++;
}

// Atomically read both counts.
static TickCounts getCounts() {
    TickCounts counts;
    noInterrupts();
    counts.tickA = rawCounts.tickA;
    counts.tickB = rawCounts.tickB;
    interrupts();
    return counts;
}

void setup() {
    // PWM at 54 kHz on OC2B = PD3 = INT1
    DDRD  |= _BV(PD3);    // pin PD3 as output
    OCR2A  = 37 - 1;      // period = 37 * 0.5 us = 18.5 us
    OCR2B  = 37/2 - 1;    // duty cycle ~ 50%
    TCCR2A = _BV(COM2B1)  // non-inverting PWM on OC2B
           | _BV(WGM20)   // mode 7: fast PWM, TOP = OCR2A
           | _BV(WGM21);  // ditto
    TCCR2B = _BV(WGM22)   // ditto
           | _BV(CS21);   // clock at F_CPU/8 = 2 MHz

    Serial.begin(9600);
    attachInterrupt(1, myInterrupt, RISING);
}

void loop() {
    static uint32_t last_time_printed;
    if (micros() - last_time_printed >= PRINT_PERIOD) {
        last_time_printed += PRINT_PERIOD;
        TickCounts counts = getCounts();
        Serial.print(counts.tickA);
        Serial.print(" ");
        Serial.println(counts.tickB);
    }
}

And here is the output:
54053 54053
108107 108107
162161 162161
216215 216215
270269 270269
324324 324324
378377 378377
432431 432431
486485 486485
540539 540539
...


text:
Ethernet nodemcu
I have a question that might be a #noob question but I am wondering if there is a board similar to the nodemcu in size that runs arduino code but instead can use ethernet to connect to the network instead of the wifi? I have already seen the connections to use one of the pins and such to connect that way but I am looking to see if there is a board that has the rj45 connection on it already.

closest I found is MKR Zero with MKR ETH shield

while I can't categorically rule it out, I've never seen such a device after hundreds of hours shopping different sites and buying about 15 different models of ESP boards over 2 years...

I don't think you'll find a single off-the-shelf product.  The closest I have managed to come to it is a Teensy 3.2 plus a WIZ820io & Micro SD Card Adaptor and a WIZ850io module, all stacked together.  Footprint-wise it's around the same as (or smaller than) many ESP8266-based boards - however it's considerably chunkier when all combined:

Awesome. Thanks all of these are great staring places for me. Thanks so much

"it's considerably chunkier". it is only the RJ-45 connector.

Yes one does exist that I know of. It's called the EtherTen and is made by an Australian company called Freetronics.

It uses the ATMega328P microcontroller that is used on the Arduino Uno. It is 100% Arduino compatible with onboard (RJ45 wired) Ethernet.
It can be purchased from Freetronics.com.au or from Roboshop.com.
Freetronics provides a number of documents and resources on the page linked above.

this is Arduino Ethernet clone. how is this similar to NodeMCU? it is not 32bit and is large.

The requirement was that it runs Arduino code. There was no requirement that it had to be 32-bit nor be compatible with NodeMCU (except for size).


text:
PMS5003 Serial Output Data to SD Issues
I'm trying to save the output of an air quality sensor to a SD card, but I'm having a few issues.
The sensor I'm using is a Plantower PMS5003 which puts out its data via serial. I've heavily tweaked the example sketch from Adafruit (here) as I'd like to use the Low Power library to sleep the unit, take a sample and note the time, write it to SD, then return to sleep.
I am getting the timestamp written no issue, but the data is coming out repeated as below:
22:13:10 - 34,55,61
22:13:18 - 34,55,61
22:13:27 - 34,55,61
22:13:36 - 34,55,61
22:13:44 - 34,55,61
22:13:53 - 34,55,61
22:14:1 - 34,55,61
22:14:10 - 34,55,61
22:14:18 - 34,55,61
22:14:27 - 34,55,61
22:14:35 - 34,55,61
22:14:44 - 34,55,61

The 8s timer appears to be working fine, but the repetition of data has me confused. I've tried adding delays and the like in case it was a lack of data but when I run that example sketch it comes screaming in over serial.
I also ditched using the software serial as I couldn't get it to stop messing with the low power library, it wouldn't ever sleep.
That and any general advice on the sketch is appreciated, it seems like its not the best way to accomplish this.
#include "LowPower.h"
#include <SdFat.h>
#include "RTClib.h"
#include <Wire.h>

SdFat SD;
RTC_DS3231 rtc;

File test;
String tString = "";
String sString = "";

void setup() {
  Serial.begin(9600);

  pinMode(10, OUTPUT);

  if (!rtc.begin()) while (1);

  if (!SD.begin(10)) while (1);
}

struct pms5003data {
  uint16_t framelen;
  uint16_t pm10_standard, pm25_standard, pm100_standard;
  uint16_t pm10_env, pm25_env, pm100_env;
  uint16_t particles_03um, particles_05um, particles_10um, particles_25um, particles_50um, particles_100um;
  uint16_t unused;
  uint16_t checksum;
};

struct pms5003data data;

void loop() {
  //LowPower.idle(SLEEP_8S, ADC_OFF, TIMER2_OFF, TIMER1_OFF, TIMER0_OFF, SPI_OFF, USART0_OFF, TWI_OFF);
  LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);

  DateTime now = rtc.now();
  test = SD.open("test.txt", FILE_WRITE);

  tString = String(now.hour()) + ":" + String(now.minute()) + ":" + String(now.second()) + " - ";

  readPMSdata(&Serial);
  sString = String(data.pm10_standard) + "," + String(data.pm25_standard) + "," + String(data.pm100_standard);

if (test) {
  test.print(tString);
  test.println(sString);
  test.close();

  delay(250);
}
}

boolean readPMSdata(Stream *s) {
  if (! s->available()) {
    return false;
  }

  // Read a byte at a time until we get to the special '0x42' start-byte
  if (s->peek() != 0x42) {
    s->read();
    return false;
  }

  // Now read all 32 bytes
  if (s->available() < 32) {
    return false;
  }

  uint8_t buffer[32];
  uint16_t sum = 0;
  s->readBytes(buffer, 32);

  // get checksum ready
  for (uint8_t i = 0; i < 30; i++) {
    sum += buffer[i];
  }

  //debugging
  for (uint8_t i = 2; i < 32; i++) {
    Serial.print("0x"); Serial.print(buffer[i], HEX); Serial.print(", ");
  }
  Serial.println();

  // The data comes in endian'd, this solves it so it works on all platforms
  uint16_t buffer_u16[15];
  for (uint8_t i = 0; i < 15; i++) {
    buffer_u16[i] = buffer[2 + i * 2 + 1];
    buffer_u16[i] += (buffer[2 + i * 2] << 8);
  }

  // put it into a nice struct :)
  memcpy((void *)&data, (void *)buffer_u16, 30);

  if (sum != data.checksum) {
    Serial.println("Checksum failure");
    return false;
  }
  // success!
  return true;
}

add Serial output to the question. are you sure that the 3 values you log are changing?

Yeah they can change quite wildly in the basic example sketch if I introduce smoke to the sensor.

You don't use the return value to check if the data was valid. If the function readPMSdata returns false, write an error message instead of the wrong data. The normal way is to store every received byte in a buffer instead of waiting for 32 bytes. For 9600 baud with an arduino uno, you can try the AltSoftSerial. Which arduino board do you use?

See I had wondered about buffer, and I recall a much different method offered for serial data on the Arduino forum itself in one of the long tutorials.
Using a regular 328 arduino at the moment, likely stick with the 328 if I move this away from the arduino. Do have quite a few alternates around however.

AltSoftSerial was a god send as well, its at least allowing the LowPower library to function as desired during this debug period

There is a mismatch in the code.
The Arduino loop function assumes that readPMSdata needs to be called just once for valid data but the function readPMSdata itself assumes that it will be called over and over again until a enough bytes are received and are valid.
The solution is to let the Arduino loop call readPMSdata over and over again, until it has valid data. It returns true when it has valid data, so that can be used in a if statement.
This might cause troubles with the rest of the code in the loop. The delay(250); may no longer be used and I don't know the best place to go into sleep mode. Therefor I removed the powerdown.
void loop() {
  if( readPMSdata(&Serial))        // call it many times to collect data
  {
    // there is valid data from the sensor
    DateTime now = rtc.now();
    test = SD.open("test.txt", FILE_WRITE);

    tString = String(now.hour()) + ":" + String(now.minute()) + ":" + String(now.second()) + " - ";

    sString = String(data.pm10_standard) + "," + String(data.pm25_standard) + "," + String(data.pm100_standard);

    if (test) {
      test.print(tString);
      test.println(sString);
      test.close();
  }
}

This I had not considered at all! I do love Adafruit for what they do, but they leave quite a bit unexplained in the long run. But the moment I read the post my mind started ticking on more appropriate ways to go about this.
Thank you!

So I'm having a bit of trouble figuring this out, how would you recommend looping readPMSdata until I get the data?

@BWulf, I have added it to my answer. Reading serial input and going to sleep don't go well together.


text:
Can't create an array of type const char*
I have something being returned as a const char* and would like to save it to an array.
I've tried this:
const char* book[amtBooks] = "";

and get this error:
error: array must be initialized with a brace-enclosed initializer

How about with const char* book[amtBooks] = { NULL };. This will initialize every book to a null pointer.

const char* book[amtBooks] is an array of pointers.
"" is an array of chars (with only a NUL character).

You can initialize an array of chars with an array of chars:
const char foo[] = "hello";

You can also initialize a pointer to char with an array of chars:
const char *bar = "good bye";

this works because of the “decay to pointer” feature of C and C++.
But initializing an array of pointers with an array of chars simply does
not make sense. An array of pointers to char could be initialized as
const char *book[] = {"hello", "good bye"};


text:
Reading names of files on sd card returning odd file names
When trying to read the file names from an sd card some are being returned with a ~1 and cutting off the full file name.
Initializing SD card...initialization done.
TEST.TXT        402
UNTITL~1        0
HELLOT~1        49
DATALOG.TXT     562288
ALONGN~1        0
done!

Is there any way I get the full file name of each file?
The code for this is from here: https://www.arduino.cc/en/Tutorial/Listfiles

That's the way the FAT filesystem works.
On the page you link to there's a link to a page on SDCardNotes.

FAT file systems have a limitation when it comes to naming conventions. You must use the 8.3 format, so that file names look like “NAME001.EXT”, where “NAME001” is an 8 character or fewer string, and “EXT” is a 3 character extension. People commonly use the extensions .TXT and .LOG. It is possible to have a shorter file name (for example, mydata.txt, or time.log), but you cannot use longer file names.

When you wrote the files to the file system you were on an OS that supports longer filenames. When filenames are too long there's an 8.3 name created automatically with chunks of characters removed and replaced with ~.

You have long filenames on your SD card. The SD library is too primitive to know what they are.
I'd suggest switching to FatFS (here is one implementation) which has the option of using long filenames.

Nice, didn't know about that.

@DaveNewton I'm not sure if that implementation enables long filenames, but the code it wraps certainly supports them.


text:
Connecting Arduino Arduino to MOSFET
I want to use my Arduino Nano to control a 12V peristaltic pump via a BDX33c N-Channel MOSFET. The pump has a maximum current draw of 1,4 A. The Arduino (via VIN) and the pump are powered by a 12V supply. I connected the parts like shown in the schematic diagram.

When I plugged the supply in, the Arduino voltage regulator and the Mosfet got really hot (I could not touch it longer than 1-2 seconds) and the RX-LED was on continously, even after turning it off and on again. The Arduino isn't recognized by my Computer anymore, so I assume it is dead.
What did I do wrong with my wiring?

I think this is not a MOSFET, but a NPN bipolar Darlington transistor

The 'schematic' shows both sides of the motor connected to ground. The 5V output from the Arduino's regulator goes nowhere. Have you connected it up like this in real life? There's a chance you have pumped 12V to one of the Arduino inputs.

The maximum base current is specified as 250mA, which is really much for an Arduino

That little blue wire on your breadboard is shorting out the motor. You have most likely now blown the transistor and maybe your power supply. The 12V may also now have made its way into the Arduino through the dead transistor and nuked the rest of it.
Alternatively, the massive base currents imposed by the shorted ground connection may have burned out parts of the Arduino.

That little blue wire on your breadboard is shorting out the motor.

That is not the problem. That blue wire is actually correct. It connects the source to ground. (-ve)
Your drawing shows the Drain of the Mosfet connected to +12 volts and the Source connected to ground. (the -ve of the supply) If you didn't have the short (blue wire from Source to ground) it still would not have worked.
You can't put an N channel mosfet in the positive side of the supply and control it from a voltage lower than the positive supply. (something the previous answer didn't even mention)
You must have the source connected to ground (as you have) but the drain has to then connect directly to the motor, and the other side of the motor goes to the +12 connection. This would be the correct way, but there still is an important omission. You need to have a diode connected across the motor to control the flyback pulse when the mosfet turns off. Otherwise the voltage spike generated by the motor's inductance will destroy the mosfet switch.
Your blue wire on the breadboard is correct. What is wrong is the red wire to the center terminal of the mosfet. The red wire should be going to the motor. The Blue/yellow connection. The green wire should be going to the mosfet's center pin.And as I said before, there needs to be a diode across the motor, with the cathode (line on the body of the diode) connected to the +ve side of the motor connection.
This is a correct drawing as far as the mosfet and motor connections are concerned. This drawing shows 5 volts being brought to the breadboard to power the motor. In your case this should be the 12 volts from the power supply.

While the beadboard may be adequate for verifying the circuit, it may cause connection problems due to the significant current that the motor will draw. Even if you wired it up properly you may still have issues due to the poor connections.
EDIT:
I looked up the specs for the BDX33B and it is a darlington transistor and not a mosfet. But in the end, all that I said also applies whether it was a bipolar transistor or a mosfet. But you need to include a series resistor as shown in the drawing I provided. You can't drive it direct from a port pin as if it were a mosfet.
Another schematic.

This shows a darlington transistor like the one you listed, and a 12 volt power source.


text:
Does a pin (input pin Arduino) still float when connected to GPIO on RPI?
I am currently testing my application on an Arduino, and I experience floating pin issues. My program reads the pin status of input pins, which are configured as
pinMode(5, INPUT);
digitalWrite(5, HIGH);

but still they tend to float sometimes.
Will this be solved when I connect the pin directly to a GPIO pin on a RPI? Specifically when the application running on the RPI is not active yet (thus the GPIO pin will not actively high or low yet).
Both the PI and and Arduino will be powered at the same time, but the application on the Arduino will be active much faster than the application on the RPI.
So my concern is that while the RPI is still booting and loading the app, the Arduino might still 'suffer' from floating pins, which gives undesirable output to the things my Arduino controls.
Or, will the fact that the RPI and Arduino both have power, share the same ground, will result in a stable input on the Arduino?
PS: not an expert on electronics, hence the question. I can't test this yet as I don't have all the hardware of this project.

You need to enable the internal pull-up resistors which are designed to prevent undefined input states on unconnected inputs.
Change
pinMode(5, INPUT);

to
pinMode(5, INPUT_PULLUP);

For more information on this see Arduino digital pins.

I would add, for OP's sake, that what they are doing used to be the way to configure internal pull up prior to arduino 1.0.1 , but this does not work in newer versions of the SDK which added the INPUT_PULLUP configuration. There are probably many tutorials and example projects still using the old pattern.

Thanks. I don't know if I ever knew that.

Thanks for the correct way of doing this. I the meantime I learned that I can also create a pulldown resistor incredibly easy! I connected a 22k resistor to ground and connected the input on my arduino to that resistor. I also connected my RPI output to that resistor. That works perfectly, no floating behavior at all. I will also give your solution a try as it even simpler. So thanks for helping out!

Good work. Most designs use the internal pull-ups as it saves the additional components. Some micros have the option of a pull-down as well. Thanks for the feedback.

Does a pin (input pin arduino) still float when connected to GPIO on RPI?

Yes. Connecting one floating pin to another floating pin doesn't make either one of them stop floating. If anything, the fact that there's now a long wire connecting them (and picking up RF) will probably make the behavior of the pins even less predictable.


text:
Calculate sensor unique address with a 8 position DIP Switch
I have a large amount of sensor boards that I need to be able to configure setting unique addresses. Each sensor is attached to it's own arduino, I'm using a 8 position DIP switch for setting the address.
I have tried diferent approaches. When I switch On and OFF I get random values. I understood that I would be able to get up to 255 possible positions, but without being able to get the proper byte data I would have to manually code each possibility, which seems wrong.
Schematic :

Code
#include "DipSwitchI2C.h"

DipSwitchI2C::DipSwitchI2C(int address)
{
    _address = address;
}

void DipSwitchI2C::begin()
{
    Wire.begin();
}

int DipSwitchI2C::read()
{
    unsigned int address = 0;
    unsigned int value = 0;

    Wire.requestFrom(_address, 1);
    if (Wire.available())
    {
        value = Wire.read();
    }
    Wire.endTransmission();

    for (int i = 0; i < 8; i++)
    {
        address += (value & (1<<i)) > 0;
    }

    return address;
}

A 8 position DIP switch can have 256 positions. And you are just calculating the sum of bits.

First of all, you must be sure that the _address has the right i2c address of the pcf8574, then you can do a Wire.requestFrom(_address,1) and a return(Wire.read()). That's all, two lines, nothing else.

it is unclear what this means .... without being able to get the proper byte data

since you have only one sensor board on any given Arduino, why do you need a unique address on the sensor board?

determine what is the value of  Wire.read() at this line value = Wire.read(); .... you may be surprised

@jsotola I have network of sensors connected by rs485. I need to be able to ask the sensor reading for every arduino from a master

As @jsotola noted the solution was simple:
int DipSwitchI2C::read()
{
    unsigned int address = 1;

    Wire.requestFrom(_address, 1);
    if (Wire.available())
    {
        address = Wire.read();
    }
    Wire.endTransmission();

    return address;
 }

Assuming that your switches are on pins 2-9 on an UNO.  Change pins to match what you actually have.
byte addressVal = 0;
for(int i = 2: i<10; i++){
    addressVal <<= 1;
    addressVal += digitalRead(i);
}

This will check each switch and add a 1 to the end of the byte.  On each iteration it shifts the contents of that byte 1 place to the left.  After it reads all the pins you have a byte with a value 0 to 255 depending on the states of the pins.

The switches are connected to the arduino by a PCF8574 multiplexer not directly to the pins.

Well then replace the digitalRead command with whatever command you use to read a pin from the multiplexer.


text:
Do some variables not hold their value when a while loop is exited?
Sorry if i'm asking too many silly questions but i'm really stumped on this one. I understand if I set a variable inside a loop that that variable won't be within scope from the outside of the loop.
Usually I find that variables declared outside of a loop will be accessible inside the loop, modifiable within the loop, and hold their value when exiting the loop but in this case that doesn't seem to be happening.
There are books on the sd card.
I'm saving the name of each book to an array from within a while loop.
When the while loop is exited the array is still null.
How can I solve this? thanks
int amtBooks = 5; //this gets set previously but im not going to show all the code

// create an array the size of the amount of books
  char* book[amtBooks] = { NULL };

// assign the name of each book to the array
  int bookNum = 0;
  while (true) {

    File entry =  root.openNextFile();
      if (! entry) {
        break; // no more files
      }

    book[bookNum] = entry.name();

    Serial.println(book[bookNum]); // <--------PRINTS FINE HERE

    bookNum ++;

  }

  root.close(); // close the stream

Serial.println(book[0]); <---ONCE OUT OF THE WHILE LOOP NOTHING DISPLAYS?
Serial.println(book[1]);

note: you have inconsistent indentation in your code .... the first line and the last two lines should be indented 2 spaces .... they are on the same level as the while (true) { line .... the three lines of the if block should be indented 2 spaces less  .......... incorrect indentation adds confusion to debugging

this is not about Arduino. it is C

variables declared outside of a loop will be accessible inside the
  loop, modifiable within the loop, and hold their value when exiting
  the loop

This is correct.

in this case that doesn't seem to be happening.

It is happening. The reason it looks like it doesn't is that
book[bookNum] is a pointer: the address of some data in memory. You
can check that the pointer does hold its value by printing it:
Serial.println((uintptr_t) book[bookNum]);

However, the statement you used:
Serial.println(book[bookNum]);

has a different meaning. It doesn't print the value of the variable
(i.e. the pointer): it prints the characters that are stored at the
pointed-to address, up to and excluding the first NUL.
Your problem comes from the fact that when you declare
File entry =  root.openNextFile();

you have a variable that is local to the loop. Then, when calling the
method
entry.name()

you get a pointer to an array of characters that belongs to the entry
object. This pointer is only valid as long as the object is in scope. As
soon as it gets out of scope (at the end of each loop iteration), the
entry object is destroyed and all memory belonging to it is released.
At this point the pointer you saved is a “dangling” pointer: it points
to an area of memory that has already been deallocated.
The proper fix is to allocate yourself the memory you need to hold the
character arrays, as in:
for (int bookNum = 0; bookNum < amtBooks; bookNum++) {
    File entry = root.openNextFile();
    if (!entry) break;
    const char *name = entry.name();
    book[bookNum] = (char *) malloc(strlen(name) + 1);
    strcpy(book[bookNum], name);
    Serial.println(book[bookNum]);
}

If you know in advance the maximum length of a book name, you could
follow the advice of Jot and Juraj and statically allocate the maximum
space you may need. That would be safer in terms of memory management.

You store a pointer to char array name in File variable entry. The entry goes out of scope (is deleted from stack) and your stored pointer points nowhere.
You need char book[amtBooks][13] = {{0}}; and strcpy(book[bookNum], entry.name());

It helps if you know where the variables are located.
Local variables are located on the stack. They are created when entering a function and vanish when exit from a function. They can even be locally inside a if, for, while or other statement when they are declared inside that statement.
Global variables have a fixed memory location. They can be used from every function.
When a pointer is created and it points to nothing, then you may not write data to where that pointer it pointing to.
You create a array of pointers, but you need memory that you can use to store data. For example: char booknames[5][20]. An array of text is often copied with strcpy().

This entire piece of code is within the main do loop. There is something weird going on because even if I declare the array globally at the very top, setting the array values from within the while loop is not persistant. If I remove the while loop I can set the values of the array.  Within the while loop the array values are present but loses the values once exiting the while loop.

That is what I was trying to explain. It helps if you know where the variables are located. The actual text in your code is stored nowhere, since you use pointers. You have to create a memory location to store those texts. Not a pointer to something or nothing, but you need a memory location for the characters of the text.


text:
What does this lines mean in RFID UID Card Reader Code?
I'm currently doing a project using RFID. I'm wondering how this lines of the code work. I know that this has something to do with getting the UID of a scanned/tapped card, but can someone please explain or elaborate to me each line, how it executes? Thank you very much.
  String ID = "";
  for (byte i = 0; i < 4; i ++) {
    ID += (rfid.uid.uidByte[i] < 0x10 ? "0" : "")
          + String(rfid.uid.uidByte[i], HEX)
          + (i != 3 ? ":" : "" );
  }

which part of the code do you understand? .... which part of the code do you not understand?

I'm finding a hard time to understand the 4th and 6th lines of this specific part, so those are operators. Thank you so much for elaborating.

those are ternary operators .... the print() function would receive one of the two strings depending on a logic test result   print( 1<2 ? "this is true" : "this is not true") ....  print( 1>2 ? "this is true" : "this is not true") ..... first one would print "this is true" .... the second one would print "this is not true"

The code formats UUID as a string of 4 hex bytes (each bytes a pair of hex digits) separated by colons.
String ID = ""

Blank the string
for (byte i = 0; i < 4; i ++){

Iterate over the four bytes of the UUID
  ID +=

Add the following to the string "ID"
(rfid.uid.uidByte[i] < 0x10 ? "0" : "") +

If the hex number to be displayed is less than 0x10, add a leading '0' to the string 'ID'. This ensures the UUIDs are all aligned and all bytes within the UUID are displayed as two hex digits (even if only one is needed). It uses the ternary condition operator, which is a compact if/then/else that can only return one of two values (rather than executing chunks of code). See https://en.wikipedia.org/wiki/%3F: for more on the ternary condition operator.
 String(rfid.uid.uidByte[i], HEX) +

Add the UUID to the string 'ID' as HEX.
   (i != 3 ? ":" : "" );

Another instance of the ternary condition operator. This one adds a colon to the string 'ID' after the hex byte unless the index is 3 (ie the last one).
 }

End of for loop.
This means that the result is nn:nn:nn:nn instead of nn:nn:n:nn: (leave off trailing colon and differing numbers of hex digits).

Thank you guys for elaborating it for me. I super highly appreciate it. :)


text:
Stacking 3 of the same shields on top of each other and instructing them in sync
Context:
I have an audio track separated into individual channels grouped by frequency and speaker location. I need to play all three of these channels simultaneously and perform instructions like play, stop, repeat, skip across all channels to keep them in sync.
This is part of an outdoor installation so the solution must be modular and robust.
If possible, the most elegant solution I could come up with is to use an Arduino Leonardo and stack 3 Adafruit Music Maker Shield on each other.
Reasons why I think it might be technically feasible:
1. Each shield can share communication over I2C

Looking at the VS1053b Datasheet (the IC used in the shield) the chip at max load consumes Maximum 60mA, and typically 37mA. Arduino can drive a max of 500mA so these three shields should consume a small portion of that.
The Arduino will also be powered via 12v power supply.

Details i'm not so clear on:

How will I differentiate between each shield when sending instructions or do I need to even need consider this if I want them to function as one?

the shield in link uses SPI

Using 12V as a power source isn't great. The voltage regulator has to burn off 7V to get down to 5V. With these 3 shield and the Leonardo itself, you are looking at around 1 Watt of power the voltage regulator is converting to heat. This will make it quite warm.

I'd personally ditch the Arduino entirely and use something more powerful. Something with an I2S interface, and connect up a CODEC with enough channels to suit your needs. Then you play a single file that has all the channels in it. You know - like surround sound does.

@Gerben So do you recommend to use a 5V 500mA power supply?

@Majenko Due to technical limitations we can't export a track to more than stereo. I'm not the audio guy, I'm the tech guy so I'm have to work with what I'm given.

A 5V supply would be ideal. Connect it to the USB, not the barrel jack.

The shields use SPI. There are more slave select pins on the shield for different devices of the shield. The first shield can use the default pins, but on next shields you must bend the default pins of the shield to side and connect them with a jumper cable to other set of pins of Arduino.
Then in sketch you need to define the select pins in constructor for each instance of the handling object Adafruit_VS1053.
Adafruit_VS1053_FilePlayer musicPlayer =
  Adafruit_VS1053_FilePlayer(SHIELD_RESET, SHIELD_CS, SHIELD_DCS, DREQ, CARDCS);
Adafruit_VS1053_FilePlayer musicPlayer2 =
  Adafruit_VS1053_FilePlayer(SHIELD_RESET, SHIELD_CS_2, SHIELD_DCS_2, DREQ_2, CARDCS);
Adafruit_VS1053_FilePlayer musicPlayer3 =
  Adafruit_VS1053_FilePlayer(SHIELD_RESET, SHIELD_CS_3, SHIELD_DCS_3, DREQ_3, CARDCS);

They will be not in microseconds sync since you must instruct them individually.
Use only one SD card because the SD library can't support more of them. Advantages of one SD card are only one cs pin and less active devices on SPI. There is no direct read by the player from SD card on the same shield.
Note: The SPI device is the SD card not the adapter. An empty adapter is nothing on bus so you can put the card for example into the shield on top and do not need bend the SD card cs pins on other shields.

The audio is sound scapes so there are no vocals or beats to align so it being microseconds out of sync will be okay.
Why use only one SD card?
Each channel will be exported to its own track and each track will be on it's own SD card which will therefore have it's own shield so they can be all played together

added to answer

I must use three separate SD cards as each channel has been exported as it's own track. So all three tracks must play at once.
I still dont quite understand why you are suggesting to use one SD card in this case.

your tracks are files. 3 files on one SD card. the player opens a file from the SD card reads the next buffer and closes the file. when the buffer is almost empty, the player opens the file, reads the next part and closes the file. the 3 players can read files from the same SD card. SD library can't work with multiple SD cards.

I understand now. Thank you for your help @Juraj

and one more note:.. the SPI device is the SD card not the adapter. an empty adapter is nothing on bus so you can put the card for example into the shield on top and do not need bend the SD card cs pins on .shields

My components have come and I started working on the project today. I have rewired the pins and have been able to communicate with multiple shields and play the files individually - but not yet simultaneously. I have a suspicion that that data rate required to play multiple tracks is lacking on the shield (I'm using a class 10 SD) but maybe I'm jumping the gun as I'm getting an "exit status 1" error when I invoke the ".useInterrupt(VS1053_FILEPLAYER_PIN_INT)" method. I will make a new post for this error.

perhaps you will need to modify the mp3 library. increase the buffer size and make changes so not all players play the buffer to end at the same time

The shield actually uses SPI.
So you will need to trace the chip select and make sure that each shield uses a different arduino pin.

Would that mean rerouting MCS, DCS and CCS for all shields?
https://learn.adafruit.com/adafruit-music-maker-shield-vs1053-mp3-wav-wave-ogg-vorbis-player/pinouts#main-control-breakouts-2-3


text:
Interfacing with an SSI sensor?
I'm trying to interface with version RM08S of this rotary encoder using an Arduino Mega. The sensor supports a "Synchro serial interface (SSI), single ended" interface. I'm unfamiliar with this protocol.
Despite the name, it doesn't appear to match the description of the formal SSI or RS-422 specification, since that requires two wires for differential clock and data lines, whereas this sensor only has a single wire for each. This makes it sound more like IIC, but without the bus-like functionality.
Googling finds very few results on interfacing the Arduino to SSI devices, much less any standard libraries. This forum thread asks a similar question, but doesn't seem to resolve the issue.
Since there's just a clock and data line, would reading from this be as simple as toggling clock, and then reading the 10-bits of data from the data line, sequentially with each clock tick, accounting for whatever bits are used to pad the packet?

On my RM08 is an RS422 Interface connected. Can i just connect Data+ to Miso and CLK+ to SCK?
@Majenko

It's just SPI.
SPI.begin();
SPI.setDataMode(SPI_MODE2);

// ...

uint8_t h = SPI.transfer(0x00);
uint8_t l = SPI.transfer(0x00);
delayMicroseconds(20); // Indicate EOT
uint16_t v = (h << 8) | l;
v >>= 4; // for 12 bit resolution, 5 for 11 bit, 6 for 10 bit etc.

For 8 bit resolution or less you only need one SPI.transfer, and subtract 8 from the right-shift amount.
Wiring is simple: clock to SCK (52 or ICSP 3) and data to MISO (50 or ICSP 1).
The timing diagrams in the datasheet (page 5) describe it all in detail.

If it's functionally SPI, why are they calling it SSI? Aren't those very different things?

It's almost SPI. Close enough to work. There is no CS pin, and timing is more critical, so they can't really call it SPI. It's a serial interface, and it's synchronous.

The datasheet notes that the clock should start high, and after a falling-edge, the sensor value is latched, and on the next rising edge, you get the MSB. For SPI, doesn't clock start low, so you won't get the MSB until the 2nd cycle (2nd bit)?

@josecanuc It depends on the "mode" of SPI. You may need to issue an SPI.setDataMode(...) to set SPI into the right phase / polarity.

@josecanuc Thanks for pointing it out, by the way. I have added the right mode call to the example above. It looks like SPI_MODE2 should do it (Polarity = 1, Phase = 0)


text:
NOT realtime MP3 decoder
I know that MP3 is the most popular audio format out there, but I need to be able to convert them to wav files for bother project I'm working on. It can be done with a PC but I would like to know if there is a way of decoding a MP3 file and turning it into a pcm wav file on an Arduino. I don't want to use an extra chip, as I do not plan on playing the MP3s, just converting them.

The mp3 audio coding is not just one mathematical calculation. To decode every mp3 file you need a complete package and enough memory. That is not something for a simple arduino board.
There are libraries to decode for example a jpg file or a mp3 file. They have restrictions and you need a faster processor.
Adafruit has made a start: https://learn.adafruit.com/native-mp3-decoding-on-arduino/, but you need a powerful non-standaard arduino-compatible board. That library does not use I2S yet.
I suggest to use a Raspberry Pi.

It's something I made a start on too. Porting the Microchip code. However, it will not, and will never, run on a little Arduino. It's intended for chipKIT boards with hundreds of kB of RAM.

Isn't there a way to decode a segment at a time? I would like to read a sector, decode it, write it to a file, then repeat. If necessary, would it be possible to use a temporary file on an sd card as spare memory?


text:
Arduino Yun can no longer send to Dropbox
A long time ago I had set up an Arduino Yun to send files to Dropbox... I tried now and it ends in "killed" when trying to install the latest Dropbox Python module.
pip install (six, urllib3, etc etc) does work individually without running out of memory. Unfortunately when I install all but Dropbox, and then put the Dropbox module code folder in the current directory, it does start to import Dropbox with import dropbox but ends up with the KILLED message.
Is there a way I can connect to my current Dropbox without it using all of the 60mb of RAM and quitting... I keep getting the error with version 2.1:

Error.Cannot connect to Dropbox
  [400] u'v1_retired'

Have you configured any swap space on your Yun?

I'd eventually figured out how to do it running the latest Dropbox module installed into the sd card where there was room.


text:
Problem with serial connection. Data garbled
I have a hardware device that sends data over the serial port and over a socket connection.
I have the TX of the device connected to the RX of the ESP8266, RX of the device to TX of the ESP8266.
Comm speed is set to 115200 on both.
Code is nothing more than
void setup() {
  // Open serial communications and wait for port to open:
  Serial.begin(115200);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }
}

void loop() { // run over and over
  if (Serial.available()) {
    Serial.write(Serial.read());
  }
}

I listen on the socket and on the serial port at the same time. On the socket port i get correct data (ASCII characters). On the serial monitor of the Arduino i get garbled data. Also, it looks like the Arduino IDE cannot cope with the volume of data. I am sending appx 100 char/sec.
Any ideas?
Update Aug 13 '18
Ok, I found out that I was trying to hook up an RS232 to an UART and that, to accomplish this, I need a RS232 to TTL converter like the max3232. I will go that road and update the question if I have it.

Ok, i found out that i was trying to hook up an RS232 to an UART and that, to accomplish this, i need a RS232 to TTL converter like the max3232.
I will go that road and update the question if i have it.

What is this mystery device?

and how is Serial Monitor connected?

Mystery device is an RFID reader. Serial monitor is connected via the USB port and launched from Arduino IDE..

What RFID reader? The reason I ask is that not all serial connections are equal. I need to know the exact device so I can look up the manual / datasheet and discover what kind of serial connection it has. There is a chance you may require extra hardware between the device and your ESP8266.

I think RS232 signals are outside the TTL limits; I don't know if you've done any permanent damage.
On the interfacing itself:
https://www.sparkfun.com/tutorials/215
On the damage part:
https://forum.arduino.cc/index.php?topic=26139.0


text:
String & Char concatenations
A newbie in Arduino- and I'm trying to concatenate string and chars ( well in python it is quite different ).
I'm trying to post a MQTT message- constructed following format to the client.publish(outTopic, "["+outTopic+"]"+ msg)
while outTopic is a char* variable, and msg is char- but I get an error for such concatenation.
please your help
#include <ESP8266WiFi.h>
#include <PubSubClient.h>

// GPIOs on SONOFF board
int LED_SONOFF = 13;
int REL_SONOFF = 12;
int PIN_SW = 14;

const char* ssid = "HomeNetwork_2.4G";
const char* password = "pswd";
const char* mqtt_server = "192.168.2.113";

WiFiClient espClient;
PubSubClient client(espClient);

char msg[50];
const char* outTopic = "HomePi/Dvir/Messages";
const char* inTopic = "HomePi/Dvir/Windows/SONOFF";
const char* inTopic2 = "HomePi/Dvir/Windows/All";
const char* clientID = "Sonoff#1";
String m1, m2;

void start_wifi() {
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected");
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());
}

void setup() {
  start_wifi(); // start wifi service
  Serial.begin(115200); // start serial service
  delay(10);

  // define sonoff gpios
  pinMode(LED_SONOFF, OUTPUT);
  pinMode(REL_SONOFF, OUTPUT);
  pinMode(PIN_SW, INPUT_PULLUP); // GPIO14 has a pullup resistor
  digitalWrite(LED_SONOFF,HIGH); // LED high is OFF
  digitalWrite(REL_SONOFF,LOW);

  // start mqtt
  client.setServer(mqtt_server, 1883);
  client.setCallback(callback);
}

void switch_on() {
  digitalWrite(REL_SONOFF,HIGH);
  digitalWrite(LED_SONOFF, LOW); // LED ON
  pub_mqtt("Switch ON");
}

void switch_off() {
  digitalWrite(REL_SONOFF,LOW);
  digitalWrite(LED_SONOFF, HIGH); // LED OFF
  pub_mqtt("Switch OFF");
}

void callback(char* topic, byte* payload, unsigned int length) {
  Serial.print("Message arrived [");
  Serial.print(topic);
  Serial.print("] ");
  for (int i = 0; i < length; i++) {
    Serial.print((char)payload[i]);
  }
  Serial.println();

  if ((char)payload[0] == '1') {
    switch_on();
  }
  if ((char)payload[0] == '0') {
    switch_off();
    Serial.print("payload: ");
    Serial.println(payload[0]);
  }

}

void reconnect() {
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    if (client.connect("ESP8266Client")) {
      Serial.println("connected");
      client.publish(outTopic, "Connected");

      client.subscribe(inTopic);
      m1="Subscribed to: "+inTopic;
      client.publish(outTopic, m1);
      if (inTopic2 !=""){
        client.subscribe(inTopic2);
        m2="Subscribed to: ";//+ String(inTopic2);
        client.publish(outTopic, m2);
      }

    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      delay(5000);
    }
  }
}

void pub_mqtt(char* msg) {
  client.publish(outTopic, msg);
}

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

  if (digitalRead(PIN_SW)==1) {
    if (digitalRead(REL_SONOFF)!=LOW) {
      switch_off();
    }
  }
  else if (digitalRead(PIN_SW)==0) {
    if (digitalRead(REL_SONOFF)!=HIGH){
      switch_on();
    }
  }
   delay(100);
}

Likely it would be best if you created a new string in which you place what you want to pass to the called method.  Guessing, you have asked if the C/C++ compiler could implicitly do this by asking it to arrange for pulling out bits of the string from flash memory (the const outTopic and the "[" characters you added in the line of code) with bits from RAM (the string msg).

You can't simply concatenate C strings like that. Instead you have to build them up into a new string.  For formatting like that the simplest way is with sprintf:
char outMessage[strlen(outTopic) + strlen(msg) + 3]; // Room for topic, message, [ and ] and terminating \0
sprintf(outMessage, "[%s]%s", outTopic, msg);
client.publish(outTopic, outMessage);

Another method is with strcpy and strcat:
char outMessage[strlen(outTopic) + strlen(msg) + 3]; // Room for topic, message, [ and ] and terminating \0
strcpy(outMessage, "[");
strcat(outMessage, outTopic);
strcat(outMessage, "]");
strcat(outMessage, msg);
client.publish(outTopic, outMessage);

You have to ensure that your "holding" string outMessage is big enough to hold everything you want to send, plus a terminating NULL character, otherwise your program will crash.
Another way of creating the "holding" variable is with alloca(). That allocates bytes on the stack for a variable - just like malloc() does on the heap, but doesn't require free()ing because it's on the stack and is reclaimed when the function exits:
char *outMessage = (char *)alloca(strlen(outTopic) + strlen(msg) + 3);

thank you- i fund first method more short and sensable. does it matter that outTopic is char* ?

%s connects to a char * data type.

I was referring to char outMessage[strlen(outTopic) + strlen(msg) + 3];

char *foo and char foo[x] are essentially the same. The second is a char * with memory allocation added in.

@Mejnko - can you please explain why +3 is needed, since for purpose of string concatenation, it is not needed - does it relevent for sending ?

One for the [, one for the ] and one for the terminating NULL character. Three in total.

I've edited my comment, after your reply :) - i ment to ask if an oridinary concatenation ( just any other 2 strings ) needn that NULL char ?

You always need the null character.