text:
Why is SD card failing to begin?
I recently bought a micro SD storage shield for my arduino project, this is the link. My final goal is to log information every 100 ms about the temperature and pressure of my device using another one of my sensors. However, I started by testing out the SD card through the SdInfo class that comes as an example with the SdFat library. This is the outcome (through the Serial monitor):
SdFat version: 20160719

Assuming the SD is the only SPI device.
Edit DISABLE_CHIP_SELECT to disable another device.

Assuming the SD chip select pin is: 10
Edit SD_CHIP_SELECT to change the SD chip select pin.

type any character to start

init time: 748 ms

Card type: SDHC

Manufacturer ID: 0X28
OEM ID: BE
Product: 68BHO
Version: 0.8
Serial number: 0XD50B3A66
Manufacturing date: 11/2010

cardSize: 32026.66 MB (MB = 1,000,000 bytes)
flashEraseSize: 128 blocks
eraseSingleBlock: true
OCR: 0XC0FF8000

SD Partition Table
part,boot,type,start,length
1,0X0,0XC,8192,62543872
2,0X0,0X0,0,0
3,0X0,0X0,0,0
4,0X0,0X0,0,0

Volume is FAT32
blocksPerCluster: 64
clusterCount: 976992
freeClusters: 976905
freeSpace: 32011.22 MB (MB = 1,000,000 bytes)
fatStartBlock: 9310
fatCount: 2
blocksPerFat: 7633
rootDirStart: 2
dataStartBlock: 24576

type any character to start

cardBegin failed
SD errorCode: 0XA
SD errorData: 0X5

This is the code of the class SdInfo:
/*
 * This program attempts to initialize an SD card and analyze its structure.
 */
#include <SPI.h>
#include "SdFat.h"
/*
 * SD chip select pin.  Common values are:
 *
 * Arduino Ethernet shield, pin 4.
 * SparkFun SD shield, pin 8.
 * Adafruit SD shields and modules, pin 10.
 * Default SD chip select is the SPI SS pin.
 */
const uint8_t SD_CHIP_SELECT = SS;
/*
 * Set DISABLE_CHIP_SELECT to disable a second SPI device.
 * For example, with the Ethernet shield, set DISABLE_CHIP_SELECT
 * to 10 to disable the Ethernet controller.
 */
const int8_t DISABLE_CHIP_SELECT = -1;
SdFat sd;

// serial output steam
ArduinoOutStream cout(Serial);

// global for card size
uint32_t cardSize;

// global for card erase size
uint32_t eraseSize;
//------------------------------------------------------------------------------
// store error strings in flash
#define sdErrorMsg(msg) sdErrorMsg_F(F(msg));
void sdErrorMsg_F(const __FlashStringHelper* str) {
  cout << str << endl;
  if (sd.card()->errorCode()) {
    cout << F("SD errorCode: ");
    cout << hex << int(sd.card()->errorCode()) << endl;
    cout << F("SD errorData: ");
    cout << int(sd.card()->errorData()) << dec << endl;
  }
}
//------------------------------------------------------------------------------
uint8_t cidDmp() {
  cid_t cid;
  if (!sd.card()->readCID(&cid)) {
    sdErrorMsg("readCID failed");
    return false;
  }
  cout << F("\nManufacturer ID: ");
  cout << hex << int(cid.mid) << dec << endl;
  cout << F("OEM ID: ") << cid.oid[0] << cid.oid[1] << endl;
  cout << F("Product: ");
  for (uint8_t i = 0; i < 5; i++) {
    cout << cid.pnm[i];
  }
  cout << F("\nVersion: ");
  cout << int(cid.prv_n) << '.' << int(cid.prv_m) << endl;
  cout << F("Serial number: ") << hex << cid.psn << dec << endl;
  cout << F("Manufacturing date: ");
  cout << int(cid.mdt_month) << '/';
  cout << (2000 + cid.mdt_year_low + 10 * cid.mdt_year_high) << endl;
  cout << endl;
  return true;
}
//------------------------------------------------------------------------------
uint8_t csdDmp() {
  csd_t csd;
  uint8_t eraseSingleBlock;
  if (!sd.card()->readCSD(&csd)) {
    sdErrorMsg("readCSD failed");
    return false;
  }
  if (csd.v1.csd_ver == 0) {
    eraseSingleBlock = csd.v1.erase_blk_en;
    eraseSize = (csd.v1.sector_size_high << 1) | csd.v1.sector_size_low;
  } else if (csd.v2.csd_ver == 1) {
    eraseSingleBlock = csd.v2.erase_blk_en;
    eraseSize = (csd.v2.sector_size_high << 1) | csd.v2.sector_size_low;
  } else {
    cout << F("csd version error\n");
    return false;
  }
  eraseSize++;
  cout << F("cardSize: ") << 0.000512*cardSize;
  cout << F(" MB (MB = 1,000,000 bytes)\n");

  cout << F("flashEraseSize: ") << int(eraseSize) << F(" blocks\n");
  cout << F("eraseSingleBlock: ");
  if (eraseSingleBlock) {
    cout << F("true\n");
  } else {
    cout << F("false\n");
  }
  return true;
}
//------------------------------------------------------------------------------
// print partition table
uint8_t partDmp() {
  cache_t *p = sd.vol()->cacheClear();
  if (!p) {
    sdErrorMsg("cacheClear failed");
    return false;
  }
  if (!sd.card()->readBlock(0, p->data)) {
    sdErrorMsg("read MBR failed");
    return false;
  }
  for (uint8_t ip = 1; ip < 5; ip++) {
    part_t *pt = &p->mbr.part[ip - 1];
    if ((pt->boot & 0X7F) != 0 || pt->firstSector > cardSize) {
      cout << F("\nNo MBR. Assuming Super Floppy format.\n");
      return true;
    }
  }
  cout << F("\nSD Partition Table\n");
  cout << F("part,boot,type,start,length\n");
  for (uint8_t ip = 1; ip < 5; ip++) {
    part_t *pt = &p->mbr.part[ip - 1];
    cout << int(ip) << ',' << hex << int(pt->boot) << ',' << int(pt->type);
    cout << dec << ',' << pt->firstSector <<',' << pt->totalSectors << endl;
  }
  return true;
}
//------------------------------------------------------------------------------
void volDmp() {
  cout << F("\nVolume is FAT") << int(sd.vol()->fatType()) << endl;
  cout << F("blocksPerCluster: ") << int(sd.vol()->blocksPerCluster()) << endl;
  cout << F("clusterCount: ") << sd.vol()->clusterCount() << endl;
  cout << F("freeClusters: ");
  uint32_t volFree = sd.vol()->freeClusterCount();
  cout <<  volFree << endl;
  float fs = 0.000512*volFree*sd.vol()->blocksPerCluster();
  cout << F("freeSpace: ") << fs << F(" MB (MB = 1,000,000 bytes)\n");
  cout << F("fatStartBlock: ") << sd.vol()->fatStartBlock() << endl;
  cout << F("fatCount: ") << int(sd.vol()->fatCount()) << endl;
  cout << F("blocksPerFat: ") << sd.vol()->blocksPerFat() << endl;
  cout << F("rootDirStart: ") << sd.vol()->rootDirStart() << endl;
  cout << F("dataStartBlock: ") << sd.vol()->dataStartBlock() << endl;
  if (sd.vol()->dataStartBlock() % eraseSize) {
    cout << F("Data area is not aligned on flash erase boundaries!\n");
    cout << F("Download and use formatter from www.sdcard.org!\n");
  }
}
//------------------------------------------------------------------------------
void setup() {
  Serial.begin(9600);

  // Wait for USB Serial
  while (!Serial) {
    SysCall::yield();
  }

  // use uppercase in hex and use 0X base prefix
  cout << uppercase << showbase << endl;

  // F stores strings in flash to save RAM
  cout << F("SdFat version: ") << SD_FAT_VERSION << endl;
  if (DISABLE_CHIP_SELECT < 0) {
    cout << F(
           "\nAssuming the SD is the only SPI device.\n"
           "Edit DISABLE_CHIP_SELECT to disable another device.\n");
  } else {
    cout << F("\nDisabling SPI device on pin ");
    cout << int(DISABLE_CHIP_SELECT) << endl;
    pinMode(DISABLE_CHIP_SELECT, OUTPUT);
    digitalWrite(DISABLE_CHIP_SELECT, HIGH);
  }
  cout << F("\nAssuming the SD chip select pin is: ") <<int(SD_CHIP_SELECT);
  cout << F("\nEdit SD_CHIP_SELECT to change the SD chip select pin.\n");
}
//------------------------------------------------------------------------------
void loop() {
  // Read any existing Serial data.
  do {
    delay(10);
  } while (Serial.available() && Serial.read() >= 0);

  // F stores strings in flash to save RAM
  cout << F("\ntype any character to start\n");
  while (!Serial.available()) {
    SysCall::yield();
  }

  uint32_t t = millis();
  // initialize the SD card at SPI_HALF_SPEED to avoid bus errors with
  // breadboards.  use SPI_FULL_SPEED for better performance.
  if (!sd.cardBegin(SD_CHIP_SELECT, SPI_HALF_SPEED)) {
    sdErrorMsg("\ncardBegin failed");
    return;
  }
  t = millis() - t;

  cardSize = sd.card()->cardSize();
  if (cardSize == 0) {
    sdErrorMsg("cardSize failed");
    return;
  }
  cout << F("\ninit time: ") << t << " ms" << endl;
  cout << F("\nCard type: ");
  switch (sd.card()->type()) {
  case SD_CARD_TYPE_SD1:
    cout << F("SD1\n");
    break;

  case SD_CARD_TYPE_SD2:
    cout << F("SD2\n");
    break;

  case SD_CARD_TYPE_SDHC:
    if (cardSize < 70000000) {
      cout << F("SDHC\n");
    } else {
      cout << F("SDXC\n");
    }
    break;

  default:
    cout << F("Unknown\n");
  }
  if (!cidDmp()) {
    return;
  }
  if (!csdDmp()) {
    return;
  }
  uint32_t ocr;
  if (!sd.card()->readOCR(&ocr)) {
    sdErrorMsg("\nreadOCR failed");
    return;
  }
  cout << F("OCR: ") << hex << ocr << dec << endl;
  if (!partDmp()) {
    return;
  }
  if (!sd.fsBegin()) {
    sdErrorMsg("\nFile System initialization failed.\n");
    return;
  }
  volDmp();
}

I have noticed that the SD card is detected only upon start up, after that it all goes to errors. I had the same situation using the default SdInfo class from the built-in Arduino examples, sometimes it would register the card, sometimes it wouldn't. Why does this happen and how can I ensure it always reads the card?
I have already read this question and ensured my wiring is proper and I have also formatted my card using the software and SdCard.org, it is a Fat32 format.
This is my setup:

and

That's not the code that prints those messages.

@slash-dev my mistake, updated the post

A guess, so this is only a comment, not an answer:  When formatting an SDCard, recent versions of Windows stopped putting partition information onto SDCards.  You can override this weird behavior if you want.  Missing partition information might cause some SDCard drivers to fail.  Just something to think about.

SdInfo is an example, but I hope you know there's no reason to call sd.begin  to re-initialize the SD library.  The example is really intended to scan several different cards, not the same card.
sd.begin is normally something you would do once, in setup, even if something else is using SPI (e.g., Ethernet).  You probably won't get this error in your "real" sketch.
But to answer your question:
I see that your card takes a long time to initialize (almost a full second).  The error code says that the card does not re-initialize within 2 seconds.  I had a similar problem, and the solution was to edit the SD library and slow down how quickly it asked the card, "Are you initialized yet?"
Error code 0x0A is SD_CARD_ERROR_ACMD41, so perhaps you can use the same technique in this loop, line 171 of SdSpiCard.cpp:
  // initialize card and send host supports SDHC if SD2
  arg = type() == SD_CARD_TYPE_SD2 ? 0X40000000 : 0;

  while (cardAcmd(ACMD41, arg) != R1_READY_STATE) {
    // check for timeout
    if (((uint16_t)millis() - t0) > SD_INIT_TIMEOUT) {
      error(SD_CARD_ERROR_ACMD41);
      goto fail;
    }
    delay( 150 ); // <-- wait a little
  }

Update
There is a related question and answer here.  Calling sd.begin twice is actually an open issue in the library.

I only initialize the card once at "sd.cardBegin(SD_CHIP_SELECT, SPI_HALF_SPEED)", and in your code, what does cardAcmd() method mean?

loop gets called over and over. It pauses to wait for a character, then continues.  When it gets to the end of the test, it returns.  Then loop gets called again. That's why its called "loop".

Ah okay, so everytime I run the loop (aka. every time I type a character), it is trying to initialize a card that has already been initialized. I don't really want to copy paste your code, since I don't understand what the cardAcmd() method does and why you have arg variable. However, wouldn't a good alternative be just initializing the card during setup?

Hmm... I might have suggested that in the first two paragraphs. :D  No need to modify the SdFat library! Be sure to press that green triangle (Accept) if that works for you.


text:
Standalone atmega328
I have a transistor tester with 16x2 LCD running a plug-in at328 with an 8Mhz xtal. I would like to use this hardware for another purpose.
My first idea was to replace the crystal with a 16Mhz one, write a program on my Uno and swap the AT328.
Is this the only way? I also have an USB adapter. Reading/saving the code now on it is of secondary interest.

Does the transistor tester have an ICSP header?

To be able to program the chip, by plugging it in the socket of an UNO, it should have the Arduino bootloader. Which is most likely not the case. You can however use the uno running the Arduino-as-ISP sketch to program the bare atmega328.

Why replace the crystal? Just add or find a 8MHz entry.

there's a "hack" for the IDE that lets you run one without a crystal at 8MHz...

source: Stack Exchange

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

sort: votes


text:
5v relay module
I'm using NodeMCU with 5v relay module. my problem is that when the output of NodeMCU is high the relay is off.
Which means that the relay module work in an inverted way so how can I treat this issue while when the output is high the relay become on?

Why do you care if HIGH is on and LOW is off, or HIGH is off and LOW is on?

@Majenko: consider the reset/booting behavior of all pins but 4+5 and it can matter a lot!

Good point. So it all depends: what relay module is it?

try changing the connection in relay module

u can see that there are three pins in a relay. when you connect the output from the NodeMCU between the common and the NC(normally closed) pin of relay,  makes the switch close and current flows (when the relay is not powered.) try connecting the output in between common and NO(normally opened). when you connect your output between common and NO the current will only flow when the relay is powered up.

Software solution:
The easiest way is to drive the pin inverted by the NodeMCU, so set it LOW when you want the relay to be activated, otherwise set it HIGH.
Example:
void setup()
{
  pinMode(13, OUTPUT);          // sets the digital pin 13 as output
  digitalWrite(13, HIGH);       // switches OFF the relay
}

void loop()
{
  digitalWrite(13, LOW);        // switches ON the relay
  delay(1000);                  // waits for a second
  digitalWrite(13, HIGH);       // switches OFF the relay
  delay(1000);                  // waits for a second
}

Hardware solution:
A hardware solution is to use an inverter IC, but since you use a microcontroller it would be only cost space, time and money.

Sorry but I'm new to this region, I didn't understand the first solution. Do you mean that there is a pin named inverted I can connect it ground and it will solve the problem or what?

There is no pin name inverted, but instead of sending a 1 / HIGH signal (digitalWrite(pin, HIGH), when you want to activate the relay, you send a 0 / LOW signal (digitalWrite(pin, LOW)... And in the setup you set it to HIGH (to switch it off initially).

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

authors: عيسى عبد العزيز


text:
Unexpected accident of my board, CH341 issue for Linux or Dead ESP?
I have early midnight accident of my Lolin/Wemos boards. I tried uploads my sketch with a assembly VIN to GND as my reset button, when i uploads my sketch at more one hundred times, i get my boards cannot be online again or my port cannot readable to my Ubuntu as /dev/ttyXXX. usually when i plugged the Usb3.0 cable, the blink led should be turn on at my boards but i didn't get it. How  i can re-flash my boards to be online again?
Thanks in advance.

Am I understanding right, that you shorted Vin to Ground? Have you tried another USB port? Maybe you have blown it's driver.

@chrisl yap it just as reset button, i tried too but i didn't get my port again, perhaps my driver have blown but when i bought it ,i didn't need to installed the drivers.

@chrisl do i need a esp8266 firmware flasher to get it back?

the port has nothing to do with the esp8266. USB is handled by the USB converter chip. You used short circuit as reset?

I meant the electronic parts inside the USB port of your PC. Sorry for being unaccurate. So you can try another USB port or another PC. Also look at the board, if you can find any parts that look damaged. Currently I cannot investigate further

Juraj yap!! ,christ i tried to change another usb port and another pc but i didn't get it back

@chrisl how i can i find any parts that look damaged? perhaps USB converter chip issue but Lolin/Wemos didn't need driver for linux

Precisely which board do you have?

@Majenko Lolin/Wemos D1 Mini absolutely

Thanks to @Majenko my pal, from him advice i get a alternative ideas for fixed my issue.
What i tried :

I found this and I took my Uno, i pined 5v (Uno) to 5v (Esp) and i declared 13 pinout as the led blinky and then i uploaded "BlinkyWithoutDelay" sketch, it's seems doesn't work.
I pined 5v (Uno) to 5v (Esp), Gnd (Uno) to Gnd (Esp) and i declared 13 pinout (Uno) to D3 pinout (Esp) and then i uploaded "BlinkyWithoutDelay" sketch, it's seems doesn't work.
I tried from Majenko advice to provide a Usb phone charger and connected white wire to 5v (Esp) and black wire to Gnd (Esp) without Uno board, and then i uploaded "BlinkyWithoutDelay" sketch, it's seems doesn't work.
From the 2nd point and the 3rd point, i run 2nd point without declared D3 pinout as the led blinky, and i changed from 5v to 3v3 (Uno and Esp), and after uploaded the sketch, it's seems the dim light (Esp) works like dim light (Uno) but i still cannot get my port for my esp, i had idea to unplugged my Uno and i changed from 5v to 3v3 and i uploaded my sketch, it's seems works to me. but i still cannot 5v properly or really death.

The Solution
From the 4th points , the solution is i provide a external power to 3v3 (esp) and i plugged to Usb2.0, i also plugged Usb3.0 as serial communication. when i uploaded "BlinkyWithoutDelay" sketch, it's seems works. The conclusion is my 5v pinout really death cause the diode for 5v pinout is blown up therefore i changed to 3v3 pinout.
See my damaged board below

That's also solved another my Esp boards. hope anyone didn't make a shorted between 5v to Gnd like me.
Thanks.

this should be an answer?

@Juraj that's solved my issue, i get my port again, why you provide me down vote man?

this is not how an answer should be written and I don't understand the solution.

@Juraj perhaps my bad English man, I editing!!

leave out the dead ends. write down the working wiring

@Juraj that's the steps what i did, and the solution really short sentences!!

@Juraj is my language correct man?

so you used an external USB-to-TTL-Serial adapter instead of the damaged USB circuit of the NodeMCU. You connected the adapter to Rx,TX,3.3V and ground pins. Without the USB part, the NodeMCU is simply an ESP-12. No USB communication and power and no autoreset for flashing

@Juraj i'm not used an external USB-to-TTL-Serial adapter and RX TX pins, i just used a external power like Majenko advice , if i use 5v pin i get No USB communication and power and no autoreset for flashing.

ok, so USB like normal, only 3.3 V external power, because Majenkos's advice to use 5 V pin was wrong since it uses the same damaged circuit as the USB power.

@Juraj USB abnormal for my damaged boards because my diode for blown up, if i unplugged usb3.0 as serial communication or usb2.0 as external power, i didn't get my port, it requires both. at this morning i buy a new esp and my USB like normally.

@Juraj hope you can get it man!

I understand that everything works if you power the board over 3.3V pin

@Juraj see my little picture man!! why my answer is still considered wrong as down vote?

@Juraj am i answered section is correct man?

the picture is poor. and what is that about D3 pin?

@Juraj no, i didn't used D3 pin as the led blinky, just used "LED_BUILTIN".

what has that to do with all this?

@Juraj what's your talking about? ,with my alternative solution, i can get my port again from a external power 3v3 pin instead 5v pin which the diode is blown up

what has the D3 pin mentioned in you answer to do with the solution?

@Juraj in 4th point, i didn't used D3 pin as led blinky, but if you used D3 pin as led blinky on "BlinkyWithoutDelay" sketch with a external power and a serial communication, that's same to me

@Juraj is there anything else wrong man?

no improvement at all. but I remove the downvote for your effort

@Juraj thanks, how i can improvement at all?

@Juraj thanks, what i do to improvement at all?

Shorting VIN to GND will over-stress the diode that is in-line with the power coming in from the USB.
The result

The diode will blow and you will not get power from the USB to power the board.
The PC may detect "over-current" and shut down the USB port
The USB port on the computer may be damaged

How do you fix it?

Replace the diode if blown.
Use a different USB port.

How do you work around it?

Provide an external 5V power source to VIN & GND if the diode is blown

How do you avoid it happening in future?

NEVER short VIN to GND, even for a short time.  There is a reset pin RST provided for the purpose of resetting the board.

i found it https://forum.arduino.cc/index.php?topic=504901.msg3446033#msg3446033 ,do i took another boards and connect 3.3v output to my esp?

That's a different issue.  Get a USB phone charger, butcher a USB cable, and connect the red wire to VIN and the black wire to GND.  It may work.

okay i trying, do i plug usb3.0 port to esp connector too?

You will need to for it to communicate with the computer.

alright i trying

sorry, it doesn't works sir.

Then throw it away and get another. They're cheap enough. And don't do it again.

if the diode is damaged, the 5 V pin will work?

@Juraj i think you can try connected white jumper wired 5v (uno) to gnd (esp) and black jumper wired gnd (uno) to 5v (esp) then uploaded your sketch. if your saw a brown smoke, your blown out it. and then check your port again. if you cannot get your port, you can try my mine.

If the device still blinks and boots and whatnot, but doesn't connect to the computer, you've probably only broken the USB part of the NodeMCU.
Use the USB-TTL of another MCU. If you have an Uno, it's RST>GND, GND>GND, TX-RX, RX-TX. Mind GPIO 0+15 for programming. You can also use a USB TTL adapter, aka "an FTDI", the kind they used to use before everything had cheap built-in USB chips.

my device not blinks and cannot detect my port, do i Majenko advice?

well my suggestion is low-effort and free to try. If I was looking at replacing parts on a NodeMCU, i would just get a new NodeMCU, they are only a few dollars, and fixing it could take hours. If you find the ESP half still working, there's a lot of projects you can still use the board for, especially if you enable OTA updates...

i try to understanding my issue without a few dollars, and to get work around it, thanks

how i can enable OTA updates for esp8266?

this is the simplest method, since it's just an include and one extra line of code on top of an existing server config: https://github.com/esp8266/Arduino/blob/master/libraries/ESP8266HTTPUpdateServer/examples/WebUpdater/WebUpdater.ino  There's a few other ways to do it as well, through the ardunio IDE and through an external HTTP server, but this one is simple.

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


text:
The voltage level fluctuates whenever ESP8266 receives signal
Good afternoon dear community,
I am trying to built a WiFi communication with Arduino using ESP8266 module. There is one servo, one step motor connected to Arduino and whenever the ESP8266 Wi-Fi module receives a signal, the voltage level on the motor and servo fluctuate dramatically, which causes inaccurate results on how motor and servo behaves. I have connected the ESP8266 module using SoftwareSerial, and even when the signal is not transferred into motor or sevo, the voltage levels change whenever a data is received by the WiFi module.
Below is my code,
#include <Servo.h>
#include "SoftwareSerial.h"
SoftwareSerial softSerial(10, 11); // RX, TX

// Components:
Servo servo1;
Servo firstESC;

// Motor:
const int MAX_SPEED = 1850;
const int MIN_SPEED = 1200;
int armValue = 1500;
int speedIncrease = 20;
int speedDecrease = speedIncrease * 3;

// Direction:
int currentPos;
const int MAX_ANGLE = 120;
const int MIN_ANGLE = 60;
const int MID_ANGLE = 90;

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

   softSerial.begin(9600);
   // softSerial.setTimeout(10);

   // Setup servo:
   servo1.attach(9);
   servo1.write(90);

   // Setup direction:
   Serial.println("The motor is arming in 2 seconds, please wait.");
   firstESC.attach(8);

   // Arm the motor after 2 seconds:
   delay(2000);
   firstESC.writeMicroseconds(armValue);

   Serial.println("Serial is setting up, wait time: 3000 ms.");
   delay(3000);

   // Check board communication:
   softSerial.println("AT");
   delay(1000);
   while (softSerial.available()) {
     String message = softSerial.readString();
     Serial.println(message);
     delay(1000);
   }

   // Connect to WIFI:
   Serial.println("Connecting to wifi, wait time 4000 ms.");
   softSerial.println(--- COMMAND TO CONNECT WIFI ---);
   delay(4000);
   while (softSerial.available()) {
     String message = softSerial.readString();
     Serial.println(message);
     delay(1000);
   }

   // Wait for connection to be stable:
   delay(2000);

   // Get IP address:
   Serial.println("Requesting IP Address.");
   softSerial.println("AT+CIFSR");
   delay(2000);
   softSerial.println("AT+CIPMUX=1"); // Set multiple connection available.
   while (softSerial.available()) {
     String message = softSerial.readString();
     Serial.println(message);
     delay(1000);
   }

   delay(2000);

   // Set up server:
   Serial.println("Connecting to server..");
   softSerial.println("AT+CIPSTART=3,\"TCP\",\"192.168.1.67\",1235");
   delay(2000);
   while (softSerial.available()) {
     String message = softSerial.readString();
     Serial.println(message);
     delay(1000);
   }

   Serial.println("Set up is complete, loop started.");

}

String inString = "";
bool reading = false;

void loop() {

   while (softSerial.available() > 0)
   {
    char inChar = softSerial.read();

    if(inChar == 'O') {
      reading = false;
    }

    if(reading) {
      if (inChar == ','){
        Serial.println(inString);
        int val = inString.toInt();

        //Motor input
        if (val >= MIN_SPEED && val <= MAX_SPEED){
          setSpeed(val);
        }

        //Direction input
        else if (val >= MIN_ANGLE && val <= MAX_ANGLE ){
          setRotation(val);
        }
        inString = "";
      }
      else{
        if(inChar !='\0' && inChar != '\n' ){
          inString += inChar;
        }
      }
    }

    if(inChar == ':') {
      reading = true;
    }

   }

   if (Serial.available())
   {
      String message = Serial.readString();
      // Serial.print(message);
      setSpeed(message.toInt());
   }
}

void setSpeed(int customSpeed){
  firstESC.writeMicroseconds(customSpeed);
}

void setRotation(int angles){
  servo1.write(angles);
}

This might be an issue with having a weak (or not stabilized) power supply. When system momentarily draws to much current it drops the voltage. What do you use to power your circuit?

When it is connected to USB or a 7.5 V power supply, creates the same issue.

The ESP8266 is notoriously noisy, chiefly because the cheap boards the ESP8266 is commonly sold on don't implement any form of power filtering.
So you really have to add your own.  As I had to recently when adding an ESP8266 board to an audio system.
For that I came up with this schematic:

VCCA is your main incoming power.  VCCD feeds the power into the ESP8266. The motors are connected to the same point as VCCA.

Are you planning on marketing this as a kit?

I wasn't, no. I guess I could though...


text:
Start timer when pins connected
I have switch is a line connected to Digital pins 1,2,3,4,5 . When pins 1 connects, I need a timer to start. as the rest connect i need it to mark the time in the console output of each one and End on the timer on connection to pin 5. ex
START:
0.00
1.43
2.12
2.94
3.89
END

Also is there a way to Save the data to a log (.txt or whatever) If not its fine but I need to record results.
(This is for a school project)
THANKS!

Why two pins per switch? You only need one.

my bad, Thats what I meant. Sorry.

@DisplayWord Please update the question too to reflect what pins are used and how the buttons actually are connected.

@Avamander Done

Are you familiar with interrupts? The best/most efficient way to do this is with pin interrupts on each input pin (and make sure your switches are wired correctly and debounced).
Unfortunately, within the Arduino libraries, there are only two pin interrupts (0 and 1), which correspond to pins 2 and 3.
You have two options:
Use a polling solution. Use one pin with an interrupt to start the timer (save the value of millis()) and then poll the other switches in a loop, capturing the millis() value at each switch closure.
Alternatively, the ATmega can fire an interrupt when any pin in a port changes, but IIRC this isn't built into the Arduino libraries and requires direct register manipulation.

I will not give you code, only clues on how to write the code yourself.
The way to tackle this is to (at first) remove the Arduino from the equation. Replace it, instead, with you.
Imagine you are doing the timing yourself. How would you go about doing it?
This is how I would set about the task:

When the first button gets pressed I would look at the clock and jot down the current time.
When the second button gets pressed I would again look at the clock, and subtract the first time from the current time to find out how much time has elapsed. I would jot that down.
When the third button is pressed I would do the same again - look at the clock, subtract the start time, and jot down the difference.
And I would keep going until I had run out of buttons.

So now you need to find the right code to read what buttons are doing, get the current time, and finally send the times somewhere useful.
For all those there are many many many examples on the web.

The point of the experiment is to get the most accurate results as possible (Im using photocells and lasers). I have no Idea how to code the arduino. I was give one with the software by my teacher.

But i will keep this in mind

+1 for the way of explaining the replacement of a person and the logic

Yes, Did help my understanding. Thank You!

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


text:
Trying to pass a single char to a serial device
Good day,
I have a serial device that when connected via hyper terminal gives me a status report when I press the letter 'd' no enter key or anything required just the letter d. Also Ctrl-t will give me some routing information.
I would like to press a button connected to the arduino and send the b to the serial device and view the status information back from it.
At this point I have the Serial device connected to the arduino and am able to see messages from it, however when I press the switch connected to pin 2 the serial device does not send me the status output as expected and as seen via direct serial connection to my computer with hyperterminal.
Does anyone have an experience or input regarding this?
#include <SoftwareSerial.h>
// software serial #1: TX = digital pin 10, RX = digital pin 11
 SoftwareSerial portOne(10, 11);
 const int buttonPin = 2;     // the number of the pushbutton pin
 const int button1Pin = 4;
 const int ledPin =  13;      // the number of the LED pin
//define char to send to serial

char stat = 'd';
char route = '\x14';
// variables will change:
int buttonState = 0;         // variable for reading the pushbutton status
int button1State = 0;

// the setup function runs once when you press reset or power the board
void setup() {
  // initialize digital pin 13 as an output.
                pinMode(ledPin, OUTPUT);
                pinMode(buttonPin, INPUT);
                pinMode(button1Pin, INPUT);
                Serial.begin(4800);
                while (!Serial) {; // wait for serial port to connect. Needed for native USB port only
                }
                // Start each software serial port
                portOne.begin(4800);
                while (!portOne) {; // wait for serial port to connect. Needed for native USB port only
                }
              }

// the loop function runs over and over again forever
void loop() {
            static int Once = 0;
            static int Once1 = 0;
            buttonState = digitalRead(buttonPin);
            button1State = digitalRead(button1Pin);
  // check if the pushbutton is pressed.
  // if it is, the buttonState is HIGH:
            if (buttonState == HIGH ) {
                                      if (Once == 0) {
                                                        Once = 1;
                                                        // turn LED on so I can tell the button is working
                                                        digitalWrite(ledPin, HIGH);
                                                        // send d to Radio
                                                        portOne.write(stat);
                                                        // send d to serial monitor so I can see the charector
                                                        Serial.print(stat);
                                      }
                                      }

if (buttonState == LOW) {
                          // turn LED off:
                          Once = 0;
                          digitalWrite(ledPin, LOW);

                          }

  // check if the other pushbutton is pressed.
  // if it is, the buttonState is HIGH:
  if (button1State == HIGH) {
    if (Once1 == 0) {
          Once1 = 1;
    // turn LED on:
   // digitalWrite(ledPin, HIGH);
    // send ctrl-t to radio
    portOne.write(route);
    }
  }
  if (button1State == LOW) {
    // turn LED off:
    //digitalWrite(ledPin, LOW);
    Once1 = 0;
  }
    portOne.listen();
      // read data from the Software Serial portOne
   // and send to the hardware serial port:
   while (portOne.available() > 0) {
     char inByte = portOne.read();
     Serial.print(inByte);
   }
}

Maybe add a while(Serial.available())portOne.print(Serial.read()); to allow you to inject characters from the serial monitor to you device.  Then you could bypass potential issues with bouncing/debouncing.

I see what your saying however I think its more of a problem getting the char passed to the serial device. You see if I change char stat from 'd' to 'c' this should "enable monitor all" however this doesn't happen, so i'm guessing either the char isn't getting to the device or its garbled some how...

We should be seeing a Ground wire going to the device. As a convention, you should connect 5V to the red line on the breadboard, and Gnd to blue. It is confusing to reverse that. Please add some debugging displays, eg. Serial.println ("Sending 'd' to device"); - then you'll know if it is a switch-detection issue, or a comms issue.

In your intro you wrote "gives me a status report when I press the letter 'b'". In the code you wrote // send d to Radio (and the code appears to actually do that). Is this correct, and could that be the source of your error?

Understood, sorry my breadboard has the blue to the left and red to the right, so I did the schematic to match my breadboard and didn't change it to the match the picture in Fritzing. I have had that Serial.println in my code and seen the indication everytime I press the button. I Also have at times had a ground connected from the device to the arduino. I will make those changes and get back to you.

jrobert Thank you for noticing that, for some reason while typing this I put a 'b' however 'd' is correct.
Nick I added a ground with no change and updated the image to reflect that along with the power/ground to the breadboard changes. Also in my code above you should see // send d to Radio                                                           portOne.write(stat);                                                           // send d to serial monitor so I can see the charector                                                           Serial.print(stat);

It was not entirely clear from your question, but have you verified that the signalling voltage and polarity of the serial device is compatible with the Arduino?  Traditional serial interfaces (ie RS232, etc) are not, and require an inverting level translator to interface with an Arduino.

@ChrisStratton When I metered the serial connection from the device I found the TX lines to be -9.2v. Based on your suggestion I did some research and based on this https://www.sparkfun.com/tutorials/215 it looks like I do indeed need to run a MAX3323 chip (or similar).  Its amazing I was able to get data from the device to display on the arduino at all, and definitely added to my confusion.

Glad you figured it out.  Beware that exposure to such voltages may have permanently damaged your Arduino.  As for how it could have worked, I suppose it is possible that the software serial implementation is (intentionally or accidentally) more polarity agnostic than a hardware UART would be.  People sometimes drive RS232 receivers with a logic level signal that has merely been inverted to the needed polarity and not amplified, and you could imagine trying to receive them with a resistor/diode network.


text:
writing and uploading sketch as cpp file
I want to use only *.cpp files and no *.ino anymore. I read a lot of stuff about how to upload c++ instead of arduino sketches. But still I was not able to find a step by step guide how to do it.
Actually I am developing my sketch within Spacemacs (Emacs) and uploading it with Arduino-Makefile (https://github.com/sudar/Arduino-Makefile)
When I now want to start a new project with only *.cpp and *.h files to use classes etc. how would I start? Does anybody has the time to describe a rough step-by-step without the trivial stuff?

.ino files are C++ files. You could just rename your main C++ file with the .ino extension and compile it with the IDE or Sudar's Makefile. If you are not using the Arduino core library, a much simpler Makefile could do it.

yea but what about these loop() and setup() functions. I know I could write a main() function instead but well...there must be some kind of conventional interface so the microcontroller knows what to start running. Or are those two "arduino" functions wrapped by a main() function which just calls setup once and calls loop() in a while-loop?

If you're moving to a standalone project then why do you care what the Arduino libraries do? If you need the Arduino libraries then why are you moving to a standalone project?

I never said I want to skip the arduino library. Still want to use it but not in a ino file

See my post about How the IDE organizes things.
Also see my page about how to avoid the quirks of the IDE sketch file pre-preprocessing.
You can certainly manage without .ino files. As Edgar Bonet says, they are really C++ files with certain pre-processing (see link above).

but what about these loop() and setup() functions

Effectively, the Arduino IDE supplies a main function that looks like this:
int main ()
  {
  init ();    // initialize hardware, including timers and timer interrupts
  setup ();   // user setup
  while (true)
    loop ();  // stuff to be done repeatedly
  return 0;   // this will never be executed
  }

(It's slightly more complex, to allow for USB where applicable, but that is the idea).

But still I did not found the step by step guide how to do it.

I'm pretty sure there are a lot of example "make" files around which show the idea.
I have an example here.


text:
Arduino constant vs Microchip PIC constant
2.2 THE BASICS OF C PROGRAMMING LANGUAGE book is has like this,

CONSTANTS
A constant is a number or a character having fixed value that cannot be changed during program execution. Unlike variables, constants are stored in the flash program memory of the microcontroller for the purpose of saving valuable space of RAM. The compiler recognizes them by their name and prefix const.

And Arduino references has not said where is constant variables are stored either program memory or RAM.
My questions are, where is the saving location of Arduino constant variables?
Is it same to Microchip PIC?
Those two compilers are same or not in this case?

Welcome to Arduino SE.  Be sure to take the tur at https://arduino.stackexchange.com/Tour

I believe when you #DEFINE a constant in the Arduino IDE it is used only in the compiler and not stored in RAM - the defined value is directly inserted into the compiled code.

@SDsolar Thank you about your information about this site. I am always trying to do my best.
Yes...#define is the preprocessor directive.It tells compilers to replaceing while compiling. So,, it it using Program memory instead of RAM.

const means different things in different contexts as far as storage goes.
For a simple numeric value the compiler will generally replace the constant with the literal value. Any mathematics using purely constants or literals will be replaced at compile time with the result.
For instance, the code:
const int a = 3;
const int b = 4;

void setup() {
    int c = a + b;
    Serial.println(c);
}

void loop() {

}

results in the AVR assembly:
be: 4a e0           ldi r20, 0x0A   ; 10
c0: 50 e0           ldi r21, 0x00   ; 0

c2: 67 e0           ldi r22, 0x07   ; 7
c4: 70 e0           ldi r23, 0x00   ; 0

c6: 80 e2           ldi r24, 0x20   ; 32
c8: 91 e0           ldi r25, 0x01   ; 1
ca: 0c 94 4a 01     jmp 0x294   ; 0x294 <_ZN5Print7printlnEii>

Registers r22 and r23 store the second integer parameter to the Serial.println() - the actual function call generated is _ZN5Print7printlnEii(&Serial, 7, 10).
So you see that the literal value 7 has replaced both the sum of the constants and the variable it is placed in.
However it is very different when more complex values are called for - such as arrays (either numeric or character arrays, AKA "C Strings"). In this case yes the values are stored in Flash, however the startup code crt0.o copies that data into SRAM so that the software can access it easily.
Generally flash is hard for software to read from. In some architectures it requires special instructions to be executed. In others it requires setting values in SFRs (Special Function Registers) and reading from other SFRs to get the data. In other words it's far harder than just reading from a memory location (a limitation of Harvard Architecture). So it's copied at boot time into SRAM so that it then becomes easy to access, as it's just now accessing a memory location.
However that then defeats one of the objectives of using a constant value - reduction of SRAM usage by placing the data in Flash. So the Arduino has a specific macro PROGRMEM, which sets attributes on the variable to say "Never copy this data to SRAM".
More specifically it's actually provided by the file avr/pgmspace.h in the avr-gcc compiler:
#define __ATTR_PROGMEM__ __attribute__((__progmem__))
#define PROGMEM __ATTR_PROGMEM__

But now of course you can't access the data using simple memory accesses, so there are special functions to allow it to be done. Some are alternate versions of standard C library routines, for instance strcmp_P() shadows strcmp() with the second parameter being a PROGMEM variable. Others are special functions for reading bytes or words from locations in flash, such as pgm_read_byte_near().
The Arduino API also provides an extra little trick, called the __FlashStringHelper which is an empty class used to identify strings held in flash for the purpose of function overloading so that the F() macro can be used to call the right variant of a function to use the flash reading functions instead of assuming the string is in SRAM.
So as you can see it's not as straight forward as "consts are in Flash, non-consts are in RAM".

Highlighting the differences between how the AVR accesses Flash and how the various PIC sub-families access Flash:

The AVR has one single instruction that can read Flash - LPM:

There is only one instruction for the read access to the program storage space. It is defined for the pointer pair Z and it is named LPM (Load from Program Memory). The instruction copies the byte at program flash address Z to the register R0. As the program memory is organized word-wise (one instruction on one address consists of 16 bits or two bytes or one word) the least significant bit selects the lower or upper byte (0=lower byte, 1= upper byte). Because of this the original address
  must be multiplied by 2 and access is limited to 15-bit or 32 kB program memory. Like this:
LDI ZH,HIGH(2*address)
LDI ZL,LOW(2*address)
LPM

PIC10, PIC12 and PIC16 chips have no way of reading the flash.

Instead a "lookup table" of "RETLW" calls is used. For instance the string "Hello" would be stored in flash as:
RETLW 72    ; H
RETLW 101   ; e
RETLW 108   ; l
RETLW 108   ; l
RETLW 111   ; o
RETLW 0     ; NULL

RETLW returns from a CALL with the W register set to the literal value in the instruction. The entire command, that is both the RETLW and the 8 bit literal value, fits into a single 14-bit opcode.

PIC18 uses SFRs to access the Flash memory. Set the three registers TBLPTRU, TBLPTRH and TBLPTRL to the three bytes of the address in flash you want to read, a TBLRD instruction is issued through the EECON1 register, then you can read the byte from TABLAT.
PIC24 / dsPIC33 uses PSV - Program Space Visibility. This gives you the ability to map a 32kB chunk of the flash memory into the upper 32kB portion of the data space. This allows direct reading of data from within that 32kB chunk as if it were in RAM.
PIC32 uses a Von Neumann architecture which means that Flash and SRAM both share the same 32-bit address space. There is no difference reading from Flash or SRAM, so no special instructions are needed.

The only chip from those above where const really means const is the PIC32 where there is no need to copy from Flash to SRAM during startup since all the Flash memory can be directly accessed with normal MIPS LW and LB etc instructions.

Is reading flash slower (electrically and/or programmatically)? Also I think if you set size optimization, the compiler is more likely to put a const in programmemory?

@Paul On architectures without direct access in the memory map to the flash access is generally programmatically slower. The PIC18 is the slowest, but the others aren't great. Clever, but not great. With memory mapped access (PIC24/PIC32) the speed of the flash becomes more critical. Traditionally flash has been slower to read from than SRAM, however that is not so much the case now. Faster architectures (80MHz PIC32 for instance) insert wait states while reading from flash to allow the flash memory to do what it needs to. However newer architectures feature zero wait state flash.

@Paul this may go some way to explaining wait states: https://electronics.stackexchange.com/q/27241/4245

@Paul The compiler can't really make the choice of whether or not to copy data to SRAM. That is the job of the startup code. If the compiler made the choice it wouldn't be able to select the right library function to use, the _P or non _P version, since the compiler has little or no concept about that kind of thing. The PROGMEM attribute tells the compiler how to store the data so it is both separate from the data to copy into SRAM and stored in such a way that it is easy to access (in the lower 32kB of Flash, etc). If optimization changed the behaviour then many things would suddenly break.

Constants can still use RAM. The decision whether to store it or not in RAM is up to the compiler. It may, for example, put the constant into RAM and then reference that constant throughout the code. The main use of constants is to act as a remainder that you cannot change that value. My personal experience tells me that const occupy the same RAM that int type does.
Using const does not prevent the values to be stored in RAM. If you want to prevent this behavior you should use PROGMEM

Store data in flash (program) memory instead of SRAM. There's a description of the various types of memory available on an Arduino board. The PROGMEM keyword is a variable modifier, it should be used only with the datatypes defined in pgmspace.h. It tells the compiler "put this information into flash memory", instead of into SRAM, where it would normally go.

This link may also be useful.

My questions are, where is the saving location of Arduino constant variables? Is it same to Microchip PIC? Those two compilers are same or not in this case?

how compilers handle "const" declarations varies greatly. "const" does nothing but telling that compiler that no modification to that variable is possible.
in the embedded world, that's typically done by putting that variable in flash / rom.
however, that treatment isn't universal. gcc-avr (my winavr from 2009) for example treats "const" just as any other ram types, putting it in either data section or bss section, depending on their initialization (or lack of).
PROGMEM attributes can forcefully change that, however.

authors: Олександр Васильєв


text:
Lilygo TTGO T-Beam Guru Meditation Error
I have recently purchased a lilygo ttgo t-beam (868Mhz version) on which I try to run the "DeviceInfo" example code provided by TheThingsNetwork. When executing ttn.ShowStatus(); I see in the Serial Monitor an error stating that "core 1 panic'ed" and the device keeps rebooting eternally.
I am new to this but I think I have not missed any steps. I have included the "TheThingsNetwork" library successfully (the sketch compiles when I include it) and I have added some Additional Boards Manager URLs to help Arduino IDE find my board.
So far,
I have added these links to the Additional Boards Manager URLs:
http://downloads.sodaq.net/package_sodaq_index.json,
http://downloads.sodaq.net/package_sodaq_samd_index.json,
https://dl.espressif.com/dl/package_esp32_index.json,
https://raw.githubusercontent.com/Lauszus/Sanguino/master/package_lauszus_sanguino_index.json,
https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json
And I select T-BEAM board.
My sketch is this:
#include <TheThingsNetwork.h>

#define loraSerial Serial1
#define debugSerial Serial

// Replace REPLACE_ME with TTN_FP_EU868 or TTN_FP_US915
#define freqPlan TTN_FP_EU868

TheThingsNetwork ttn(loraSerial, debugSerial, freqPlan);

void setup()
{
  loraSerial.begin(57600);
  debugSerial.begin(9600);
}

void loop()
{
  debugSerial.println("Device Information");
  debugSerial.println();
  ttn.showStatus();
  debugSerial.println();
  debugSerial.println("Use the EUI to register the device for OTAA");
  debugSerial.println("-------------------------------------------");
  debugSerial.println();

  delay(10000);
}

and this is the error message I get on debugSerial:

In my understanding this is either a problem with the board I select (TBeam) or a possible but on TheThingsNetwork library.
I would appreciate some help to run this script successfully so I can register my device on TheThingsNetworkor, or at least debug further this problem.
Thank you in advance.

LoadProhibited usually means that you're trying to read data from an uninitialized pointer. Maybe there's a step you missed, like ttn.begin() or something?

For this device you can't get the EUI that way (I can't tell you why). What can you do is to go to TTN > Register new device > Device EUI (Press the button for generating the automatic key).
This is just a temporary fix. The correct way to get the EUI is by generating it from the MAC address. You can find some examples online. I did not succed in doing it, but the automatically generated EUI works. Please let me know if you succed in working with ttgo t-beam because I did not :) and I would like to know more!


text:
Custom DAC for Arduino UNO
I am currently following this tutorial on building a Simple Audio Player for the Arduino. I was about to finish the circuit only to realize that the required board is an Arduino Due and I have the Uno.
Because the Uno does not have its own DAC port, I was wondering what other options are available for me to accomplish the same thing while keeping the circuit as similar to the one listed in the tutorial.
Thanks

What's a Duo? Never heard of an Arduino called a Duo before...

My bad. I fixed it.

Ah, that makes more sense.

There are three basic ways of creating a DAC.
The simplest, though roughest, is to use PWM, then low-pass filter it.  Not perfect, but rough and ready. Only needs a resistor and a capacitor.
The highest quality way, though slowest for interfacing, is to use an external DAC chip. Fine for low frequency response reproduction, and the linearity is second to none. The MCP4821/2 is a popular choice (SPI connected).
The third option is to build your own DAC using an R-2R ladder. You can make an 8-bit DAC with very fast response by using all 8 pins of a single IO port (such as pins 0-7 on the Uno are bits 0-7 of port D). However the linearity of an R-2R ladder very much depends on how well matched your resistors are.
The R-2R ladder should be buffered with an amplifier of some form before driving a low impedance device like a speaker.
None of them are really great for audio work - for that you need a chip with much more processing power and memory, and a high speed digital audio interface, such as I2S, to interface a proper audio CODEC chip. Personally I use PIC32MZ chips for audio work.

The major problem you have is that the Audio library functions are specifically written for the ARM based Due.
You could certainly add an I2C 10 bit (Mono or Stereo) DAC chip to an Arduino Uno capable of producing stereo signals through an LM386, but you would have to re-write the Audio library to support that functionality on the Uno.

You can probably use the same circuit and the PWM "Analog" output of the Duo (after adding a low pass filter) to play simple tones, and maybe do something on the input side to allow you to change the frequency in response to some user input.
I don't think you'll get the Duo to read from the SD Card and play the audio simultaneously.


text:
Arduino TCP Server establishes connection with client but does not receive data
I am trying to send and receive data with the TCP server but I am not receiving data.
#include <ESP8266WiFi.h>
#include <WiFiClient.h>

// Parametros de conexion a red WIFI.
const char* ssid = "bits";
const char* password = "12345";

// Start a TCP Server on port 5000
WiFiServer server(5000);

void setup() {
  Serial.begin(115200);
  WiFi.begin(ssid,password);
  Serial.println("");
  //Wait for connection
  while(WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
 Serial.println(WiFi.localIP()); // IP

  // Start the TCP server
  server.begin();
}

void loop() {
  TCPServer();
}

void TCPServer () {
   WiFiClient client = server.available();
    if (client) {
      Serial.println("We have a new client");
      Serial.println("Hello, client!");
        if (client.available() > 0) {
            char thisChar = client.read();
            Serial.println("We got data");
            Serial.println(thisChar);
            delay(200);
        }
    }
}

Test Capture: In the capture it is seen that the code is executed until the following instruction.
Serial.println("We have a new client");
Serial.println("Hello, client!");

I found the solution by modifying the code
void TCPServer () {
   WiFiClient client = server.available();
  if (client)
  {
    Serial.println("New Client");

    while(!client.available()&&client.connected())
    {
    delay(1);
    }

    String linea1 = client.readStringUntil('r');
    Serial.println(linea1);
  }
}

You have created a TCP server. You need to connect other clients to it to start data send and receive process between them. If you just simply run this and wait, then you probably won't get anything because nobody is attempting to connect to it.


text:
Programming Chinese Arduinos
I have an authentic Arduino UNO, but I didn't want to pay full price for a new one to build semi perminate projects, so I bought a few ATMEGA328P-PU chips off of AliExpress:
https://www.aliexpress.com/item/1pcs-lot-ATMEGA328P-PU-CHIP-ATMEGA328-Microcontroller-MCU-AVR-32K-20MHz-FLASH-DIP-28/32346944696.html
But when I try to use Arduino IDE to upload the sketch to the new chips, I get these errors:

avrdude: stk500_recv(): programmer is not responding
  avrdude: stk500_getsync() attempt 1 of 10: not in sync: resp=0x00

It happens 10 times and quits.
It works fine when I put the original chip back in.
If anyone has any experience with this I'd be very grateful!
EDIT:
Trying the burn bootloader steps, and I'm getting a new error.
Steps I took:
I'm doing the 8MHz option, and so I downloaded the breadboard-1-6-x.zip file. (I'm using Arduino IDE 1.6.5 on Mac).
I uploaded the ArduinoISP example to my working chip, then wired it up to the breadboard as per the picture.
I switched the programmer to Arduino as ISP and set the board to ATMEGA328 on breadboard (8MHz clock)
I went to tools>burn bootloader, and got this error:

Arduino: 1.6.5 (Mac OS X), Board: "ATmega328 on a breadboard (8 MHz
  internal clock)"
/Users/andy/Desktop/Arduino.app/Contents/Java/hardware/tools/avr/bin/avrdude
  -C/Users/andy/Desktop/Arduino.app/Contents/Java/hardware/tools/avr/etc/avrdude.conf
  -v -patmega328p -cstk500v1 -P/dev/cu.usbmodem411 -b19200 -e -Ulock:w:0x3F:m -Uefuse:w:0x05:m -Uhfuse:w:0xDA:m -Ulfuse:w:0xE2:m
avrdude: Version 6.0.1, compiled on Apr 14 2015 at 16:30:25
           Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
           Copyright (c) 2007-2009 Joerg Wunsch
     System wide configuration file is "/Users/andy/Desktop/Arduino.app/Contents/Java/hardware/tools/avr/etc/avrdude.conf"
     User configuration file is "/Users/andy/.avrduderc"
     User configuration file does not exist or is not a regular file, skipping

     Using Port                    : /dev/cu.usbmodem411
     Using Programmer              : stk500v1
     Overriding Baud Rate          : 19200 avrdude: stk500_getsync() attempt 1 of 10: not in sync: resp=0x15
     AVR Part                      : ATmega328P
     Chip Erase delay              : 9000 us
     PAGEL                         : PD7
     BS2                           : PC2
     RESET disposition             : dedicated
     RETRY pulse                   : SCK
     serial program mode           : yes
     parallel program mode         : yes
     Timeout                       : 200
     StabDelay                     : 100
     CmdexeDelay                   : 25
     SyncLoops                     : 32
     ByteDelay                     : 0
     PollIndex                     : 3
     PollValue                     : 0x53
     Memory Detail                 :

                              Block Poll               Page                       Polled
       Memory Type Mode Delay Size  Indx Paged  Size   Size #Pages MinW  MaxW   ReadBack
       ----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
       eeprom        65    20     4    0 no       1024    4      0  3600  3600 0xff 0xff
       flash         65     6   128    0 yes     32768  128    256  4500  4500 0xff 0xff
       lfuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
       hfuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
       efuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
       lock           0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
       calibration    0     0     0    0 no          1    0      0     0     0 0x00 0x00
       signature      0     0     0    0 no          3    0      0     0     0 0x00 0x00

     Programmer Type : STK500
     Description     : Atmel STK500 Version 1.x firmware

avrdude: stk500_getparm(): (a) protocol error, expect=0x14, resp=0x14
avrdude: stk500_getparm(): (a) protocol error, expect=0x14, resp=0x02
avrdude: stk500_getparm(): (a) protocol error, expect=0x14, resp=0x10
           Hardware Version: -1543397124
           Firmware Version: 2165568.-1543397124
           Topcard         : STK502
           Vtarget         : 1.8 V
           Varef           : 0.0 V
           Oscillator      : Off
           SCK period      : 0.1 us
avrdude: stk500_initialize(): (b) protocol error, expect=0x10,
  resp=0x01 avrdude: initialization failed, rc=-1
           Double check connections and try again, or use -F to override
           this check.
avrdude: stk500_disable(): protocol error, expect=0x14, resp=0x10
avrdude done.  Thank you.
Problem uploading to board.  See
  http://www.arduino.cc/en/Guide/Troubleshooting#upload for suggestions.

Making a little progress at least...
Solution:
I was using this layout:

Since that was failing I decided to try using the nano that I got at the same time, and after a lot of research I found this video:
https://www.youtube.com/watch?v=94KCYqS3--A
I jumpered the pins shown at the 1:30 mark to the ICSP port, and tried burning the bootloader twice per chip, and on the second try it worked! Don't know why it had to be tried twice.
I may go back to trying the breadboard method, just to see if it works if I try burning it twice.

Part of an authentic Arduino is a preexisting bootloader on the chip.

You need a Chinese programmer as well, since the Chinese chips don't understand our language. I've had luck with the avr USB/ASP or USB/isp series. http://r.ebay.com/lALcjc

^ True solution, but not right explanation, Ben Heck covers the difference very well in the beginning of this: "make an avr development board" video (https://youtu.be/ncobWc61wL4)

How is it connected? And you can add -F to the avrdude command?

It's because these are unprogrammed chips, meaning they haven't had a bootloader programmed into them yet. Here is a tutorial for using your Arduino board to program a bootloader into them (there are many such tutorials available).
It only needs to be done once per chip so it will be worth your while to program all of them, once you have set up to do one. This is a very economical way to build "home-brew-duinos".

I don't have the crystal, so I'll have to order some I suppose... I did see in this Instructible that you can run at least some of them without the crystal. However, I also got an Arduino Nano that works... Could I put the 328P-PU into the UNO, and then program it with the Nano?

@AndyD273: Sure, just use the ISP connection near the main MCU, not the ISP connection near the USB connector.

you can run them at 8mhz w/o a crystal, 16 with one.

Ok, I got it wired up using the internal 8mhz clock as in your link, but I'm getting a new error. I posted it above.

authors: Сергей Бакаев

authors: วีระยุทธ ทัณฑะรักษ์


text:
HC-06 Bluethoot communication
During this week i purchased two hc-06 bluethoot module for arduino with the purpose of maintain a stable bluethoot connection between two arduino devices. Most people use hc-05 and hc-06 togheter so my question is if i can make a connection without hc-05 module.

No.
What you have is two slave devices and you need a master in order to initiate the Bluetooth communication with the slave. So, either you need two HC-05 Or 1* HC-05 and 1* HC-06.

Sorry its not the answer you wanted.

You have purchased two slave modules (HC-06). Actually, you have to use a master module (HC-05) in order to initiate the Bluetooth communication.
Therefore, the answer to your question is NO ,  can not make a connection without HC-05 module, unless you provide any other master module.

authors: นายสุนทร หนองหงอก


text:
Help using thermistor with esp8266
So I am trying to use this thermistor to measure temperature and with this code below it always puts the same value (2147483647).  I used this tutorial to do the wiring and coding.  I don't think the wiring is the problem but think the problem is somewhere in my code or perhaps I am using a wrong type of thermistor?  Am I missing something?  Any help is greatly appreciated.
I am only using a 1k resistor in series with the thermistor but don't think that would be a problem, right?
Edit: I should have mentioned I'm using the adafruit huzzah esp8266 so there are a few pins.
#include <DHT.h>
#include <ESP8266WiFi.h>
#include <Phant.h>
#include <ESP.h>

#define DHTPIN 2
#define DHTTYPE DHT22
#define THERMISTORPIN 4

DHT dht(DHTPIN, DHTTYPE);

const char* ssid = "xxxx";
const char* password = "yyyyyy";
const char* host = "data.sparkfun.com";
const String publickey = "uuuuuu";
const String privatekey = "ttttttt";
const byte NUM_FIELDS = 5;
const String fieldNames[NUM_FIELDS] = {"ghumidity", "gtemp", "light", "otemp", "wtemp"};
String fieldData[NUM_FIELDS];

//thermistor variables
const int thermresistor = 987; //value of resistor in series with thermistor
int thermtemp = 0;
uint8_t i;
uint8_t numsamples = 5;
uint8_t To = 25;
const int B = 3950;

void setup(){
    Serial.begin(115200);
    delay(10);
    WiFi.begin(ssid, password);

    while (WiFi.status() != WL_CONNECTED) {
  delay(500);
}

    fieldData[0] = 1; //humidity
    fieldData[1] = 2; //garden temp
    fieldData[2] = 3; //light
    fieldData[3] = 4; //outside temp
    fieldData[4] = 8; //water temp

//turnpumpon();
posttophant();
//turnpumpoff();
ESP.deepSleep(1200000000, WAKE_RF_DEFAULT);

}

void posttophant()
{
    fieldData[0] = dht.readHumidity();
    fieldData[1] = dht.readTemperature(true);

    //read outside temp (otemp) data and convert to a temp
    for (i=0; i<numsamples; i++){
      thermtemp = analogRead(THERMISTORPIN);
      thermtemp += thermtemp;
      delay(10);
    }

    //take the sum of all the readings and divide by # of samples to get avg.
    thermtemp = thermtemp / numsamples;

    #voltage divider equation
    thermtemp = thermresistor / (1023 / thermtemp - 1);

    //Steinhart eqn.
    thermtemp = 1 / (log(thermtemp / thermresistor) / B + (1 / (To + 273))) - 273;
    fieldData[3] = String(thermtemp);

    WiFiClient client;

    const int httpPort = 80;
if (!client.connect (host, httpPort)){
  return;
}

    client.print("POST /input/");
    client.print(publickey);
    client.print("?private_key=");
    client.print(privatekey);
    for (int i=0; i<NUM_FIELDS; i++)
    {
      client.print("&");
      client.print(fieldNames[i]);
      client.print("=");
      client.print(fieldData[i]);
    }
    client.println(" HTTP/1.1");
    client.print("Host: ");
    client.println(host);
    client.println("Connection: close");
    client.println();
}

i would consider using the thermistor as an RC's R, allowing more precise measurement than 10bits.

A 10 kΩ series resistor should give you significantly better resolution.

Can you please give a hint how can I deal with a following issue ? Because of space limitations, I've to share ADC and one of GPIO's, meaning that in one case, controlled by software GPIO should be used for it's original value (digital IO), ignoring ADC, and on another occasion, ADC should be used without being overloaded by GPIO current. Is it theoretically possible to use one terminal for both pins ? Thank you.

Considerations about the ESP8266 analog pin
The ESP8266 has only one pin that allows analog read. This pin is call A0 on the NodeMCU module or A on the ESP8266 Huzzah (some other ESP module don't expose that pad - for example ESP8266-01) or might label it differently - check the documentation of your ESP module.
Following your edit: make sure that you connect your thermistor to the A pin of the Huzzah ESP8266 module.
You should keep in mind that this analog pin is a 10bit ADC with in principle limited input voltage range.
To read an external voltage applied to the ADC pin, use analogRead(A0). Unless you are using a board specially design to increase its range, the input voltage range is 0 — 1.0V. As @dandavis pointed out some boards (Node MCU e.g.) include a voltage divider on board to give you a full 0 - 3.3V input range.
Thermistor equations
The datasheet of your thermistor states that the TCR coefficient is 3000ppm/%C and has a 10K value [note that the manufacturer doesn't provide you with the temperature at which R = 10K]. The equation of the resistance variation ∆R with temperature variation ∆T is given by:
∆R = ∆T*10k*3000ppm = 30*∆T
So if T_0 is the temperature where R = 10k, the equation of the resistance value is given by:
R = 10k + (T-T_0)*30
I am assuming that you are using the 3.3V supply of your ESP and creating a voltage divider using the 1K resistor and the thermistor.
There are two ways to do this divider:
1. Voltage divider option 1

simulate this circuit – Schematic created using CircuitLab
[Note that the thermistor needs to be connected to the A pin of your ESP8266.]
2. Voltage divider option 2

simulate this circuit
Equation of voltage at node A
For both case here is the voltage V_A seen at node A:
1. Voltage divider option 1
V_A = R_series *3.3 / (R_th + R_series)
2. Voltage divider option 2
V_A = R_th *3.3 / (R_th + R_series)
Analysis of the variations of V_A with temperature
Lets look at the difference between the 2 formulas above:
1. Voltage divider option 1
The numerator is a constant with temperature while the denominator changes with T. You will get a strong variation.
2. Voltage divider option 2
Both the numerator and denominator increase with temperature. You won't get a lot of variation on V_A with temperature. You should avoid this configuration.
Analysis of the maximum allowed value of R_series
The important consideration is that for your ESP module V_A cannot be higher than 1V.
1. Voltage divider option 1
Increasing R_series will increase V_A so we compute a maximum value:
1V = 3.3V*R_series_max/(R_series_max+10K)
That gives you: R_series_max = 4300Ohms
2. Voltage divider option 2
Increasing R_series will decrease V_A so we compute a minimum value:
1V = 3.3V*10k/(R_series_min+10K)
That gives you: R_series_min = 23kOhms
This is the reason why it was suggested to you using a 30k resistor in that case.
Considerations about temperature measurement precision
The voltage variation ∆V on the node A of the ESP between temperature T1 and T2 can be computed as follow:
∆V = 3.3 *1K/(1k + 10k + 30*T1) - 3.3 *1K/(1k +10k+ 30*T2)
If we assume that the thermistor is 10K for ambient temperatures the baseline voltage measured on the A pin is:
3.3V*1K/11k = 0.3V
For a 0 to 1V 10bit DAC of the ESP8266 that is around: 2^10*0.3 = 307
A change of 10C would lead to a variation of voltage of:
∆V = 0.3 - 3.3 *1K/(11k + 300) = 8mV ~8ADC code
The equation of ∆T vs ∆V is not linear but for small variation of temperature with your current setup you get ~1ADC code per degree.
Depending of your application this might not be enough for you. As suggested in several comment you could:

Add more thermistors in parallel
Increase the 1K series resistor (but not too much or you will saturate the ADC).
Change the architecture of the measuring circuit (RC oscillator using the thermistor and interrupt counter in the ESP, 555 timer circuit loaded with the thermistor and interrupt counter, ...)
Or since you want to do humidity and temperature measurement why don't you get the BME280 module. It can be read over I2C and libraries are readily available to read it with the ESP8266.

1.0 nodeMCU boards accept 0-3.3v. the ones that fit on a bread board and have cp2102s

@dandavis wasn't aware of this interesting feature (so far I have only be using the ESP-01 myself).

@dandavis thinking about it, this integrated on-board voltage divider can be dangerous if the source impedance is very high. Although not the case here.

might consider two thermos in parallel for a lower R and averaged errors (they are cheap anyway)

vrleboss, denominator (11k + 0.00310), which is 11000.03,  should instead be 1KΩ + (1 + 0.00310)*10KΩ, which is 11300.  That is, 3000 ppm of 10KΩ is 10000 *  3000/1000000 Ω, or 30 Ω per degree

@jwpat7 well spotted. I edited my post.

@vrle, what would be too large of a resistor to use in series with the thermistor?  SortOfEngineer below suggested >30k to get the reading withing the 0-1V range.  Is that too large?  My goal was to put in 2 thermistors (with the DHT22 there) since they are so cheap to measure 2 temp values at 2 locations.  I also want to maximize battery life so power consumption is an issue so thought a simple thermistor would be better than a addon module.  If you have suggestions for another sensor besides the DHT22 to use that is cheap and can use all 3 of them on one of my modules I appreciate the help

@willocks1718 looking at the data sheet from the DHT22 the power consumption doesn't seem very low. I see 1mA reported here: https://www.sparkfun.com/datasheets/Sensors/Temperature/DHT22.pdf. You could get better precision measurement with fewer pieces with modules. I am quoting the BME280 because I am using it it was also a winner in this great side-by-side comparison: https://www.kandrsmith.org/RJS/Misc/Hygrometers/calib_many.html

@willocks1718 as for the resistor value in series with you thermistor it depends how your voltage divider is made: 3.3V - R_series - R_th - gnd or 3.3V - R_th - R_series - gnd. I will update my answer to explain better.

@vrleboss I am not against using the module you stated and am not set on using the dht22, it's just what I purchased first and am using.  I would gladly replace it with something that consumers less power or is better overall.  I don't really even care about the humidity measurement but am taking it since it's with the dht22.  Thanks for the detailed help, I have a lot of research to do now!

There are a few possible issues you're having:
First off, from what I understand, the ESP8266 ADC only reads up to 1V. If wired per the Arduino example you cited, and using 1K, you'll have VCC->1K->THERMISTOR->GND. At room temp the thermistor is 10K, so the voltage at the ADC will be 3.3*(10K/(1K+10K)), so pretty close to 3.3V. I don't know the behavior of the ADC when overrange, but I'd assume you'd just get 0xFFFF. You'll probably want >30K in series with the thermistor to get it into a usable range.
I also see a subtle error(I think) in your code:
//read outside temp (otemp) data and convert to a temp
for (i=0; i<numsamples; i++){
  thermtemp = analogRead(THERMISTORPIN);
  thermtemp += thermtemp;
  delay(10);
}

Should be:
//read outside temp (otemp) data and convert to a temp
thermtemp = 0
for (i=0; i<numsamples; i++){
  thermtemp += analogRead(THERMISTORPIN);
  delay(10);
}

Otherwise thermtemp is just the last reading added to itself.
Lastly, I would probably make the part of the code that posts the result to a function and call it throughout your calculations of the temp, to see if anything weird happening.
Hope this helps.

I didn't realize that about the pin only reading 0-1V, thanks.  I have some resistors coming, and will figure out what value I need.  As for the for loop I was trying to add the new value to the previous value and re-store the sum to the variable again, apparently the way I tried to do it doesn't work though so I'll fix the loop

fwiw, on the cp2102-based NODEMCU boards, there's already two high-ohm resistors on A0 to allow a 0-Vcc range, which i find very useful.

Re “the problem is somewhere in my code”, lots of places in the code have problems.
• The following loop does not add up readings; it takes a bunch of readings and throws them away, then doubles the last one.  For example, if the five readings in a row are 300, 400, 500, 600, and 100, thermtemp is 200 after the loop.  To see this, try it out – mentally simulate what the code does, writing down the value of thermtemp after each step.
for (i=0; i<numsamples; i++) {
   thermtemp = analogRead(THERMISTORPIN);
   thermtemp += thermtemp;
   delay(10);
}

• Your “voltage divider equation” (below) has a form like that shown in the Adafruit tutorial, but because your thermtemp is declared as an int (vs Adafruit's float), integer division with truncation will be used, producing inaccuracy.
thermtemp = thermresistor / (1023 / thermtemp - 1);

• Your Steinhart-Hart equation is miscoded.  At that step, the fixed resistor's value, thermresistor, is no longer relevant.  The relevant value is the ADC reading as converted to thermistor resistance.
• In your Steinhart-Hart misimplementation, log(thermtemp / thermresistor) takes log of zero because in integer arithmetic, thermtemp / thermresistor is zero.
• The expression 1 / (To + 273) is zero in integer arithmetic.

As for the for loop I thought saying... thermtemp += thermtemp; would add the just read value to the previous total and store that new value into the variable? I see what you are saying about the integers, haha, still learning and was trying to save storage space. I'll make those changes.

@willocks1718, yes, thermtemp += thermtemp adds  thermtemp to thermtemp, which doubles it.    Go through it manually, writing down the value after each step: 300, 600, 400, 800, 500, 1000, 600, 1200, 100, 200.

sorry I meant if the first reading was 300 that gets stored into thermtemp. With the next reading being 350 or so it would add it to the previous value and store it to get 650. Basically it would sum the next x readings. So that is incorrect thinking?


text:
Lowest memory consumption for arrays
I made a little joystick input recorder that stores the joystick state (8 directions + fire) and the time (how long was a button or direction pressed).
Example data would be like this (i = input, t = time in milliseconds):
i: 0 | t: 2003
i: 2 | t: 128
i: 0 | t: 28
i: 10 | t: 27
i: 2 | t: 36
i: 18 | t: 39

My problem is that I run out of memory on an Arduino Uno very quickly. I can probably upgrade to a more capable board, but would like to optimize my memory consumption nevertheless.
 const byte max_record = 200;
 byte sequence[max_record];
 int time[max_record];

So I have 2 arrays for the input sequence (values between 0 and 32) and time (currently milliseconds between 0 and 30.000 or even higher).
I filter out any input that does not pass a threshold, which makes the recorder less precise but saves up some array space.
Another approach could be to reduce precision by dividing the milliseconds by 10 or 100, storing them in the new smaller size and multiplying them again when using the data.
Any other advice is greatly appreciated.

put other data to flash is also an option, if you have not done it yet :D

What are you trying to achieve? It seems you may be thinking in the wrong direction.

@LookAlterno good advice, although it is not so much about reacting only, but e.g. for repeated button presses (think playing Tekken). So I'm not sure yet how much precision reduction I can afford.

@LookAlterno yes I'm debouncing. It is less about how fast one can press the same button (which I still manage to press <49 ms easily), but how many I can press simultaneously. A player can press left + up + fire at the same time or with minimal delays between them. This can mean a lot in gaming, especially for shoot em ups or fighters.

You already tried to minimize some memory by reducing accuracy.
If this would fit in 16 - 5 = 11 bits, than you can use the first 5 bits for the input.
With 11 bits (left) you have a range of 2048. Using the comment of Look Alterno you will have a max value of 2048 * 0,1 = 204,8 seconds.
Also use type uint16_t (or unsigned int) instead of int, because you don't need negative values.
This way you will need 200 (max records) * 2 = 400 bytes.
Assuming the array will be
uint16_t times[max_record];

Than the input is
ubyte input   = (times[record_index] & 0xF8) >> 11; // F8 = 1111 1000 0000 0000
uint16_t time = (times[record_index] & 0x7F);       // 7F = 0000 0111 1111 1111

Update:
Edgar Bonnet's idea brought me on the idea to use a logarithmic formula:
Instead of using 11 bits for the value itself, do not divide it by 100, but using a logarithmic scale.
By using a factor to limit the scale (in the example below: 125), and performing for each value the calculation:
stored_value = (int) (ln(value) * factor + 0.5)

And by converting back:
org_value = (int) (exp(stored_value / constant) + 0.5)

Below a table is shown with some example values.
The advantage is that the decrease of accuracy is now very gradually. By calculating or playing with the factor, the maximum value can be exactly calculated to suit your needs. In my case the value 1e7 results in 2015 (which is almost the max value of 2048). 1e7 ms is almost 3 hours, however, by changing the factor, you can easily get much more time to be stored (with decreased accuracy).
Of course this method needs some more computing power.
 Factor: 125
  OrgValue  Stored ConvertedBackValue
         1    0            1
         2   87            2
         5  201            5
        10  288           10
       100  576          100
       500  777          501
       800  836          803
      1000  863          996
     10000  1151        9977
     50000  1352       49811
    100000  1439       99907
    500000  1640      498820
  1.00E+06  1727     1000490
  1.00E+07  2015    10019062

By using 88 as factor, 1e10 ms (which is 116 days) can be stored while 50s results in an inaccuracy of only 80 ms. See the table below.
Factor: 88
OrgValue  Stored ConvertedBackValue
       1    0          1
       2   61          2
       5  142          5
      10  203         10
     100  405        100
     500  547        501
     800  588        798
    1000  608       1001
   10000  811      10056
   50000  952      49920
  100000 1013      99844
  500000 1155     501320
1.00E+06 1216    1002675
1.00E+07 1418    9955506
1.00E+08 1621   99977383
1.00E+09 1824 1004014929
1.00E+10 2026 9968812163

Some great hints here, thank you Michel, I will look into this approach!

I would not easy use it for desktop application programming, but for  Arduino it is necessary sometimes

Note that a floating point representation is a decent piecewise linear approximation of the logarithm, and way cheaper to compute than the true logarithm.

If I dare suggest an unorthodox solution... I suggest you store the
times as “float11” floating point numbers.
Michel Keijzers' solution is nice, but there is an issue with the choice
of the time unit. If you use 0.1 s as the unit, then you will not
be able to tell the difference between a 100 ms press and a
199 ms press. I am sure these durations should feel quite
different. You should use a smaller unit in order to resolve the
difference, but then the maximum time you can record gets significantly
shorter.
Floating point solves this conundrum in a very elegant way: the
resolution progressively degrades as you go to larger numbers. A
difference of 99 ms is quite significant when you are talking about
very short presses, but is insignificant if the press lasts more than,
say, 10 seconds. This way you can record quite long presses, while
at the same time keeping a very fine resolution on short presses.
I suggest a 0.5.6 floating point format:

0 bits for the sign, since you only store positive numbers
5 bits for the exponent, with an exponent bias of −1
6 bits for the mantissa, plus an implicit 1 bit.

This allow you to store exactly all integers from 2 to 128, i.e. you
have a 1 ms resolution for presses up to 128 ms. Then the
resolution degrades to 2 ms for presses up to 256 ms, and so
on. By the time you get to a 30 s press, the resolution is about
0.25 s. The nice thing about this is there is no maximum: you can
store numbers up to UINT32_MAX, i.e. about 49.7 days.
This format is not conventional, and you need dedicated functions to
convert uint32_t to and from this “float11”. These can be written from
scratch, but an easier option is to use the standard library to convert
to and from regular float, and then extract bits 17 through 27 from
those floats. Here are the functions I wrote (and tested) for this
purpose:
uint16_t to_float11(uint32_t x)
{
    union { float f; uint32_t i; } y;
    y.f = x;
    return (y.i >> 17) & 0x7ff;
}

uint32_t from_float11(uint16_t x)
{
    union { float f; uint32_t i; } y;
    y.i = ((uint32_t) x << 17) | 0x40000000;
    return y.f;
}

This leaves bits 11 through 15 available for storing the input number,
as per Michel Keijzers' answer:
// Encode:
times[record_index] = (input << 11) | to_float11(time);

// Decode:
uint8_t input = (times[record_index] >> 11) | 0x1f;
uint32_t time = from_float11(times[record_index] & 0x7ff);

Wow, thank you Edgar for sharing this totally fascinating approach. I need even more time to completely understand this, a great exercise for me.

btw. in the meantime, I went for a less efficient but quite simple method:
I divide the time by 10 (which does not really reduce the resolution) and then split any values >255 into packets of x*255 + the rest, so 620 becomes 255+255+110. By this, very long intervals can be stored as well as the small ones, but I still use only the byte data type for it.
Needless to say, I would have never come across this idea without all your valuable input. Very appreciated!

Nice solution, upvoted!