text:
ESP8266 Webserver does not respond
I am trying to reach the webserver running in my Wemos D1 Mini compatible board.
I am trying one esp8266 example using Arduino examples "WifiManualServer" code below.
I have replaced the SSI and password for my wifi network in the lines
#define STASSID "my wifi ssid"
#define STAPSK  "my secret"

/*
    This sketch demonstrates how to set up a simple HTTP-like server.
    The server will set a GPIO pin depending on the request
      http://server_ip/gpio/0 will set the GPIO2 low,
      http://server_ip/gpio/1 will set the GPIO2 high
    server_ip is the IP address of the ESP8266 module, will be
    printed to Serial when the module is connected.
*/

#include <ESP8266WiFi.h>

#ifndef STASSID
#define STASSID "my wifi ssid"
#define STAPSK  "my secret"
#endif

const char* ssid = STASSID;
const char* password = STAPSK;

// Create an instance of the server
// specify the port to listen on as an argument
WiFiServer server(80);

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

  // prepare LED
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, 0);

  // Connect to WiFi network
  Serial.println();
  Serial.println();
  Serial.print(F("Connecting to "));
  Serial.println(ssid);

  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(F("."));
  }
  Serial.println();
  Serial.println(F("WiFi connected"));

  // Start the server
  server.begin();
  Serial.println(F("Server started"));

  // Print the IP address
  Serial.println(WiFi.localIP());
  server = WiFiServer(80);
}

void loop() {
  // Check if a client has connected
  WiFiClient client = server.available();
  if (!client) {
    return;
  }
  Serial.println(F("new client"));

  client.setTimeout(5000); // default is 1000

  // Read the first line of the request
  String req = client.readStringUntil('\r');
  Serial.println(F("request: "));
  Serial.println(req);

  // Match the request
  int val;
  if (req.indexOf(F("/gpio/0")) != -1) {
    val = 0;
  } else if (req.indexOf(F("/gpio/1")) != -1) {
    val = 1;
  } else {
    Serial.println(F("invalid request"));
    val = digitalRead(LED_BUILTIN);
  }

  // Set LED according to the request
  digitalWrite(LED_BUILTIN, val);

  // read/ignore the rest of the request
  // do not client.flush(): it is for output only, see below
  while (client.available()) {
    // byte by byte is not very efficient
    client.read();
  }

  // Send the response to the client
  // it is OK for multiple small client.print/write,
  // because nagle algorithm will group them into one single packet
  client.print(F("HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n<!DOCTYPE HTML>\r\n\r\nGPIO is now "));
  client.print((val) ? F("high") : F("low"));
  client.print(F("

Click here to switch LED GPIO on, or here to switch LED GPIO off."));

  // The client will actually be *flushed* then disconnected
  // when the function returns and 'client' object is destroyed (out-of-scope)
  // flush = ensure written data are received by the other side
  Serial.println(F("Disconnecting from client"));
}

Once I compile and upload the sketch, the sketch is able to connect to my wifi network.
The following is the output in the serial monitor.
20:45:12.633 -> Connecting to <text replaced xxxxxxx>
20:45:13.247 -> ........
20:45:17.551 -> WiFi connected
20:45:17.551 -> Server started
20:45:17.551 -> 192.168.0.39

I am able to verify the client connection in my wifi routers network management UI.
The espboard is connected and assigned the IP as in the output (192.168.0.39).
When I launch browser and try to get http://192.168.0.39/gpio/0, the request times out.
from my windows 10 pc, tried ping on 192.168.0.39, the Request timed out.
From the sketch I see the following lines in the loop() function:
  WiFiClient client = server.available();
  if (!client) {
    return;
  }
  Serial.println(F("new client"));

The execution never reached the line Serial.println(F("new client"));.
I had tried inserting the line server = WiFiServer(80); after the wifi connection is established.
Please share your thoughts on why the server.available() is not successful?

Is your windows 10 PC on the same subnet? Does your WiFi router impose WiFi Isolation?

remove the line server = WiFiServer(80);

I think you have to call server.on() somewhere so the server does actually serve an url. Which library do you use btw (there is nothing behind #include for me)?

@SimSon, this is not ESP8266WebServer library

@Juraj, thanks for the suggestion. I have now removed the line server = WiFiServer(80). The issue is resovled. The server is now reachable. Thanks your help.


text:
AT 09 BLE module not transmitting data
I have recently started working with the Arduino Pro Mini 5v/16Mhz and an AT 09 BLE module for an IoT project. I am controlling the BLE module using Software Serial and am leaving the hardware serial for for my laptop. I am using an app called "Serial Bluetooth Terminal" on Android to send/receive messages. The BLE module is able to receive messages and the "AT" command is also working. But when I try to get the BLE module to send a message, I get no response in the app. Any idea why this is happening and how can I resolve it?
My connections are:

Laptop -> Arduino UNO, MB-102(USB to breadboard power adapter)
Arduino UNO(without IC) Rx -> Pro mini Tx0
Arduino UNO(without IC) Tx -> Pro mini Rx1
Arduino UNO(without IC) RESET -> Pro mini Rst
MB-102 5V -> Pro Mini Pin RAW
MB-102 GND -> Pro Mini Pin GND
Pro Mini Pin 2 -> AT 09 TXD
Pro Mini Pin 3 -> AT 09 RXD
Pro Mini Pin VCC -> AT 09 VCC
Pro Mini Pin GND -> AT 09 GND

This is my code:
#include<SoftwareSerial.h>

SoftwareSerial ble(2, 3);

int statePin = 4;
char c;
void setup()
{
  Serial.begin(9600);
  ble.begin(9600);
  ble.print("AT\r\n");
  delay(100);
  while(!ble.available())
    Serial.print(".");
  while(ble.available())
  {
    Serial.print(char(ble.read()));
  }
}

void loop()
{
  while(ble.available() > 0)
  {
    c = char(ble.read());
    delay(10);
    Serial.print(c);
    ble.print(c);
  }
}

This is the first time I am posting here so please tell me if I missed out on any information.

You have not connected the STATE signal?

Yes. That is correct. Was I supposed to? Edit: The state pin does not seem to be doing anything. It seems to be grounded irrespective of connection status. Verified with a multimeter.

So my AT 09 module is most likely faulty. I got a new HM 10 and connected it without changing any connections or code and it worked like a charm.
I do not know the exact nature of the defect but since the chip was responding to commands, I think the PCB might have been damaged.

source: Stack Exchange

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

sort: votes


text:
Problem with connecting ESP8266 to arduino
I have:

Arduino Uno
ESP8266

Problem:
I see SoftAP and can connect to it. But I can't send AT-commands to ESP8266 from Arduino.
I use Arduino app v.1.6.5 for send command to ESP8266 via Arduino. But I don't get answer. And ESP8266 doesn't blinking.
I use this scheme:

Please, help me. I'm trying to fix this is very time consuming.

I had the same problem. I used SoftwareSerial library, so you should set baud rate as 115200 for communication with esp8266. It might look like this:
#include <SoftwareSerial.h>

SoftwareSerial esp8266(2,3);

void setup()
{
  Serial.begin(9600);
  esp8266.begin(115200);
}

It helped in my case.

You must need to add another power supply, which will give to the wifi module not just the correct voltage (3v) but the mA that it need.  / other thing you may need to do is connect the ground of Arduino to Ground of the power supply. For me works good.
the connections would be like this

esp TX     > arduino dpin 10
esp RX     > arduino dpin 11
esp CH     > to VCC 3V
esp RST    > to pushbutton connected to gnd
esp GpIO 0 > none
esp GpIO 2 > none
esp VCC > power supply 3v
esp GND > power supply gnd

I had the same problem. I solved it doing the following:
Connect Arduino TX to a voltage divider (to get 3,3V) and then to TX on ESP8266
Connect Arduino RX to RX on ESP8266
It should work!.
Please read the information on this link
http://rancidbacon.com/files/kiwicon8/ESP8266_WiFi_Module_Quick_Start_Guide_v_1.0.4.pdf

From memory the ESP8266 can pull more current than the Arduino can supply so you need a separate 3.3V supply.
You also need 3.3V/5V logic level shifters on ALL you connections between the Arduino and the ESP, because the ESP of the different in logic levels.

authors: Виталия Александров

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

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


text:
ESP8266 can't read parasitic DS18B20 temperature (reset during conversion, 85°C)
tl;dr at the end
I was running two DS18B20+PAR temperature sensors without any problems for the last two years on an ESP-01 module running on 3.3V on GPIO 2 using a 4.7K pullup resistor.
Now, wanting to develop a new firmware I started the development with new versions of everything (Arduino IDE and libraries), but now, with the exact same hardware setup that worked flawlessly for two years, the sensor always returns 85°C (error code for reset during conversion). I suspect that somehow, I don't know how, the ESP does not leave the data pin powered anymore.
To test this, I recompiled and flashed my old firmware that was running fine for two years and lo and behold, it still returned 85°C. Trying to isolate the issue, I flashed the old binary of the firmware and it returned the correct temperatures again.
To isolate the issue further, I tried numerous versions of the OneWire (2.3 to 2.3.2) and DallasTemperature (3.7.3 to 3.7.9) libraries, but to no effect. I am still getting 85°C all the time.
I also tried to compile it using Arduino IDE and PlatformIO, but both yielded the same issue still.
Trying on another ESP8266 (Wemos D1 mini and nodeMCU) did not change anything.
Slowly I am suspecting that the issue lies in the ESP8266-Arduino framework updating something or a change in the compiler, which now breaks keeping the data pin configured as output during the conversion.
Older versions of the ESP8266-Arduino framework (tried 2.2, 2.3, and up until latest) also produced the same error still.
A workaround, of course, is to use a lower value pullup resistor so that the sensors take power through that instead of the powered microcontroller pin. (One parasitic sensor requires 1K, two 470 Ohms) But this is not a solution.

Last weekend I debugged a bit deeper into the issue:
The OneWire library definitely leaves the pin as output (last macro called is DIRECT_MODE_OUTPUT()) and also the correct bit in the GPE pin mode register is set to output (1) during the conversion.
As far as I can see, the pin should be at 3.3V, but the oscilloscope definitely says the pin is dragged down too low (1.5V) during conversion. So it's only pulled up that far by the 4.7K pull-up resistor and not the GPIO pin for whatever reason...
I poked around here and there in the library but could not find the error. From what I can see, the code says that it should be working fine and my old binary says the hardware works fine too, but obviously it doesn't...
After five hours of unsuccessful debugging I gave up again.
I also opened an issue at the official OneWire GitHub Repo, but got no reaction in two weeks.
I will update this question in the following days by testing on other Arduino IDE versions and operating systems. Also, I want to try out the library fork from orgua to see if the issue happens in his library too.

tl;dr
- DS18B20+PAR with 4.7K pull-up always returns 85°C (error code indicating too little power on the data line) with newly compiled firmwares
- Hardware setup is working fine with old .bin
- Old code and new code freshly compiled yields error
- Doesn't depend on the library versions or what sketch is used
- Lower value pull-up resistor works, but is a dirty workaround
Hopefully someone else is able to reproduce or has already experienced this issue and is not satisfied with the workaround of using a lower pull-up resistor?

What pin are you using?

I am using GPIO2. (But it's still weird, that the unmodified hardware setup works with the old binary but not the new)

The datasheet specifies a "strong pullup" specifically mentioning using a MOSFET for the strong pullup. Still it doesn't answer the question of why the old libraries worked.

Do you know what versions were used to build the old binary? Can you guess based on the lastest libraries as of the build date?

The datasheet probably assumes an old microcontroller with no output drivers, that can't supply even a mA. The ESP8266 however has an output driver of up to 12mA, so that should be no problem. At least in theory, as the old code worked flawlessly.

I compiled the old code roughly in June 2016 and already tried all libraries from that date accordingly (as stated in the text), but still with the same result . Although I did not try an old Arduino IDE version from that time yet. But I will soon.

One last possibility: it looks like the esp8266-arduino package included a OneWire library in version 2.0.0 but it was removed in 2.1.0.

I just tried that today, still no change at all 85°C all the time...


text:
Arduino Due not properly detecting SD card
I have an SD breakout for my Due that isn't properly detecting the SD card. On one card, it cannot detect at all, and the other it says that the SD isn't formatted with FAT, even though it is. Here is my wiring:

simulate this circuit – Schematic created using CircuitLab
So, I broke out my oscilloscope and started probing lines. One in specific I got worried about, is the SCK line and it's bouncing, specifically from the inductance of the jumpers. This is the SCK line from my scope:

My reaction was to put some buffer caps on there, and so I put 2x 300pf capacitors in parallel for a total of 600pf. This is the waveform as measured after I put in the debouncing caps:

This is much more tolerable, and I can accept this level of bouncing for the SCK line, as I doubt that there will be much misfiring. I upload the SD card test sketch that's on the website, here is the output:
Initializing SD card...Wiring is correct and a card is present.

Card type: SD2
Could not find FAT16/FAT32 partition.
Make sure you've formatted the card

What does The Arduino Due have that makes it hard to detect the card?

Remove the caps please. Perhaps the scope itself creates the overshoot.
The Due is not special. It should work.
Can you tell what kind of SD memory cards and which SD module you use ?
Try the SD Formatter, see the post at the Arduino.cc forum: "Don't Format SD cards with OS utilities!".
Some SD memory cards are not compatible. Perhaps you have more luck with an older 1GB or 2Gb SD memory card.

I don't think the scope itself has overshoot. The Resistance of the scope is 10M, and the caps help the inductions' load, as where they wouldn't with the scope being the inductive load. I'll try the formatter. Thank you!

Tried both. no cheese

Do you have long wires ? Or a breadboard with bad contacts ? Or a low voltage level of the power ? Everything runs at 3.3V ?

Actually, the SD card breakout has a Logic level translator that translates 3.3 to 1.8 volts. The wires themselves are long (2x4"). Another thing that I noticed is that the MOSI line never seems to go too low while transmitting signals (while my oscilloscope is watching). It seems to be always high.

That not very long, I hope it is not a flat ribbon cable, those cause a lot of crosstalk. Can you give a link to your SD card ? Every SD card and SD socket I use with Arduino is 3.3V. Some cards work with 1.8V as well, but for the Arduino you better stick with the old fashion 3.3V.

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


text:
constant current or constant voltage power supply to use with RGB shield with high power LEDs
So, I got an arduino uno and a RGB shield from velleman for christmas because I mentioned I might want to do a project with high power LEDs - a neat surprise, but now I have to use it (:
The shield can do PWM on an external power supply and this can be wired through to the high power LEDs itself. I aim to power about 10W of LED light in total, with different colors in order to make good use of the board. Can I go for Option 1? If not, what would you advise?
Option 1
As high power LEDs need a constant current, I am inclined to connect a constant current supply as the external supply of the board (assuming all channels' LEDs need the same current).
Update: I talked to an electrician and a constant current supply typically works on a PWM basis; putting this in series with the PWM of the shield is not smart.
Option 2
Alternatively I could connect a standard constant voltage supply and make sure that the current is within limits:

One option would be to use resistors; but, with 12V DC and 350mA I would need like 33 Ohm resistance dissipating 4 Watts of power, which is inefficient.
Alternatively there are DC voltage to constant current LED drivers which will take care of the constant current for me; I could put those at the exits of the shield for the LEDs. They supposedly have a better conversion efficiency than the resistors, but I do have any knowledge about their performance with PWM as input; but I have serious doubts they would like that type of input. Furthermore, these drivers also often have PWM capabilities. This kind of module would render the shield functionality largely useless.

What kind of led(s) are you using?

@Gerben I did not buy a specific LED yet, I was looking into the star platine LEDs, say, xcree or the ones I linked. I heard from LEDs with included current limiters but did not find any (and I do not know how they will react to PWM signals). I would prefer RGB LEDs as I want to mix colors. I am very open to suggestions (:

Option 1 is a boost circuit. At least it says it is. So you can't use it for a single led. I'd go with the last option. If you want something cheaper, you could use this board though you have to solder to the PWM directly, as there isn't a pad/connector for it.

Uhm, I think you'd better go with the solution velleman propose you, so use a common RGB strip. I think you can use a 5m 5050 rgb strip with 60 leds/m (they usually take 40mA/m/channel, so it is 6A in total). Put a 12V 10A supply and you have a lot of RGB leds. Avoid the 3825 led strips (what they call 3825 rgb led strip actually has R, G and B separated leds; you want the 5050 version, which have R,G and B in the same package)

Your thinking and reasoning is pretty much spot on.
The board you have is basically a trio of high current low side switches. So yes, you need something to limit the current, and as you have noted resistors are not going to be very efficient.
The best way to drive high power LEDs is, as you know, with constant current. However, you need a constant current source per LED channel, not one single one for the whole board. That means three individual constant current sources, each providing the right current for the LEDs you are driving on that channel.
It's possible to roll your own cheap constant current sources using LM317T linear voltage regulators (http://diyaudioprojects.com/Technical/Current-Regulator/). It's a cheap option, though pretty much as in-efficient as using resistors, just easier to deal with the heat sinking.  Note that on the LM317T the tab is live, so you must use three separate heat sinks for each channel.
My personal preference though is to use PWM capable constant current sinks. My favourite is the CAT4101 which can deal with up to 1A per channel (more if you parallel them) and uses a single resistor to set the current. It has a PWM input that you can drive direct from an Arduino's PWM pin. Of course, as you note, that then makes your nice shield redundant.

Now that I have the board I feel kind of inclined to use it (:
I understand you correctly, that I should not use the board with a constant current source (even per channel) as they will likely not be able to handle the fast PWM input voltages well?
Given the effort of the LM317T, I am more prone to use resistors; I might put LEDs parallel, each line with its own resistor. Choosing a low supply voltage should further limit unwanted power dissipation.

Resistors are by far the simplest solution, yes. Spreading the load as much as possible can only be a good thing :)


text:
How to convert char[] to int with fail\success control?
this is more like C question, but i failed to google this.
i expect a command parameter in char[], but there may be no argument passed at all, so i need to try to parse this char[] to int and if there is garbage instead of a number, notify user.
i also need to be able to parse negative (with -sign char) numbers from char[].
how can i do this? thanks.

Try http://www.atmel.com/webdoc/AVRLibcReferenceManual/group__avr__stdlib_1ga3a1fe00c1327bbabc76688a7a1d73370.html

Alternatively http://www.atmel.com/webdoc/AVRLibcReferenceManual/group__avr__stdio_1ga5507d0e1bbfd387fbb2ffcfd8f5dca6f.html that will allow fail\success control.

Easiest is maybe http://www.atmel.com/webdoc/AVRLibcReferenceManual/group__avr__stdlib_1gaf8ce3b8dae3d45c34c3b172de503f7b3.html then you can check that 1) a number was parsed, 2) if there are any extra characters, etc.

It isn't doable, reliably, with the given specs. If the array has garbage in it, it won't necessarily fail to parse as an int. That said, you can try to parse as an int with atoi() or sscanf(), as suggested in the comments, and report that it did or did not parse, but not necessarily whether it is valid in some respect.
If you're in control of the array, zero its first element. Then if you get back a non-empty string, at least you'll know some command parameter had been placed in it.

but sscanf did nice job, returning 0 if it can't fill the int variable, thus telling that there is no valid int argument passed.


text:
Identify UUID of HC-06
I'm currently learning about using BLE with Arduino and iOS. From what I understand (correct me if I'm mistaken), each type of BT device has a UUID. I'm using a HC-06 module connected to my Arduino. How do I find out what the UUID of a HC-06 is? I've been looking through data sheets to no avail.

Voting to close: this is a question about the HC-06 or iOS development, not about Arduino.  That said, you might want to see what a BTLE scanner program like "light blue" or similar can find.

In Android, I used this UUID to connect to HC-06,
  socket = device.createInsecureRfcommSocketToServiceRecord(UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"));

  inputStream = socket.getInputStream();
  outputStream = socket.getOutputStream();

You can use this UUID in your Android code, But over iOS, I think the Bluetooth is really a completely different hardware specs.
Hope I helped

Android use the SPP protocol as the HC-05 and HC-06, but it seems iOS don't. So comunicating with an iOS machine would be difficult.

Well guess what, HC-06 is not low energy so no iOS device will ever see that module despite whatever uUid you have, so go and get a bluetooth 4.0 aka BLE module


text:
Matlab interfacing with arduino ERROR
I installed the MATLAB support package for arduino in my MATLAB r2013a today.
Now I plugged on my Arduino in my usb port.
And ran the command:

a = arduino()
Error: Undefined function or variable 'arduino'.

When I get:

a = arduino('COM18')
Undefined function 'arduino' for input arguments of type 'char'.

I have checked that this package has been installed.

It is grey.

Any help will be appreciated.
Thanks very much
Anupam.

Is the directory where the arduino package is installed added to the matlab path?

I a newbie to matlab. Can you please eloborate.I did not change any paths while installing.It was the default one.

Navigate to the package install dir in matlab and right click you should see the add to path option there. If the dir is on the Matlab path it wont be greyed out

actually theres a separate Arduino site on stack exchange you might find better help there

It is grey.See edited question

Arduino support within MATLAB came with Matlab-2014a onwards, you are using R2013a
Arduino support within SIMULINK came with Matlab-2012a onwards
for your release you can only interact via a simulink model


text:
Using an External ADC with Arduino
For my project I have to measure a  signal of the order of few microvolts.
As we know the least an Arduino can measure is ~5mV, due to its 10bit ADC and 5V reference voltage.
A solution to this problem can be to use an external ADC (16bit, I think will do).
Can you please guide me on this problem.Is it possible to use a external ADC,if yes how should I.Any other simple solution ?
Thank You
Anupam

You could get around 1mV resolution by using the internal 1.1V voltage reference inside the Arduino. However the maximum voltage you can measure will also be lowered to 1.1V

You can get resolutions as fine as 7.8125µV / LSB using a MCP3428 (4 true differential channels). I sell them on a shield on eBay: http://www.ebay.co.uk/itm/High-Precision-Analog-Data-Acquisition-Board-for-Arduino-chipKIT-etc-/182123969426

What is the range of input voltages you need to measure? If it is for example 0 to 10 mV, and the built in ADC's 10 bit resolution is sufficient, you could put an amplifier with a gain of 500 in front of the ADC and get 10 uV per count. Noise may be a problem however

Range is 0- 30mV (atleast)

Yes, if you have a 0 to 30 mV signal that you need to measure to an accuracy of 2 microvolts, you'll need an ADC with an effective number of bits (ENOB) of at least 13.9 bits and an amplifier to make the signal to match the range accepted by the ADC.
Most ADCs pretty much require some sort of op-amp or differential amplifier between such low-level input signals and the ADC input pins.
A few ADCs have a differential amplifier already built in -- that makes things a lot easier to get working, but I don't know if any of such ADC available would meet the other requirements of your project.
I don't know any way to make such high-resolution measurements other than using a dedicated external ADC chip.
You'll want to read the ADC datasheet -- some of them, and so far all the microcontrollers I've seen that claim to have a built-in "16 bit ADC", have an effective number of bits (ENOB) worse than the 13.9 ENOB you need at the sampling rates I typically use.
Adafruit has a very nice tutorial describing how to connect the 12-bit ADC ADS1015 or the 16-bit ADC ADS1115 to an Arduino.
The Arduino playground has a brief tutorial describing connecting a 12-bit ADC MCP3208 or a 13-bit ADC MCP3304 to an Arduino.
I see from the Arduino blog and other sites that people have connected some even higher resolution ADCs to an to an Arduino board, including
the 24-bit Linear LTC2440 ADC;
the 18-bit LTC2400 ADC (24 bit at 5 samples per second); and
the 24-bit ADC TI ADS1220.

Arduino blog. "Archive for the ‘ADC’ Category"
Peter Oakes. "Arduino UNO, Using precision ADCs and DACs". (video tutorial: connecting the 24-bit ADC TI ADS1220 to an Arduino).
Martin Nawrath. "Connect a LTC2400 High Precision 24 Bit Analog to Digital Converter ... to the Arduino"
John Boxall. "Tutorial – Arduino and the TI ADS1110 16-bit ADC".

Sounds like a fun project.
Good luck.
EDIT:

Steve Luce. The LTC2440 24 BIT ADC and the Arduino Uno.

Everyone that uses an ADC needs some antialiasing filter between the signal and the ADC.
People that measure very faint signals usually need some sort of amplifier between the signal and the ADC.
You may find the list of suggested op amps on p. 7 of the AMP03 datasheet useful.
Because historically ADCs were expensive (and high-resolution ADCs were unavailable), people have developed many clever tricks for processing signals before feeding the processed signal into a relatively low-resolution ADC.
(Lock-in amplifiers, chopper amplifiers, manual precision gain adjustment, manual precision offset adjustment, heterodyning, etc.)
Have you tried asking "What sort of amplifier do I need to measure ((something)) with a 16-bit ADC" at https://electronics.stackexchange.com/ to learn some of those tricks that specifically apply to ((something))?

Thank You so much David for your answer.Yeah MCP3304 looks like a better ADC as my signal has a frequency of 10Hz.The processing has to be done before 100ms.ADS1115 samples at a very low rate.Is it possible to measure 10microvolt using mcp3304 ?

The ADS1115 can be programmed to several different sampling rates, from 860 samples/s to 8 samples/s. Often that is adequate for a nominal 10 Hz analog data signal. What are you really trying to measure?

Yeah I think you are right David. ADS 1115 is good enough.My signal is pulsed ,0.5-1microsecond long at a period of 100 milliseconds.I am using a peak detector for this.To acquire the data(from the peak-detector,i.e capacitor) i need an ADC.


text:
use Nodemcu to program Attiny85
I have a dev board for my attiny85.
when connecting it to the computer I get "unknown USB device(device descriptor request failed)"
although I have the needed drivers, so I thought of trying using my nodemcu.
Tried connecting the SPI (to the nodemcu hmiso;hmosi;hcslk;hcs)and upload using "arduino as ISP" and compitable settings(https://www.hackster.io/arjun/programming-attiny85-with-arduino-uno-afb829).
pressing "burn bootloadre" using this way gives me errors:
"avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 1 of 10: not in sync: resp=0x03
......
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 10 of 10: not in sync: resp=0x03
Error while burning bootloader."
***EDIT:
After changing a line(#define USE_OLD_STYLE_WIRING) in ArduinoISP (from example)
the error code changed a bit and it shows up much faster:
"Arduino: 1.8.13 (Windows Store 1.8.42.0) (Windows 10), Board: "ATtiny25/45/85, ATtiny85, Internal 8 MHz"
avrdude: stk500_getsync() attempt 1 of 10: not in sync: resp=0x04
avrdude: stk500_getsync() attempt 2 of 10: not in sync: resp=0x30
avrdude: stk500_getsync() attempt 3 of 10: not in sync: resp=0x61
avrdude: stk500_getsync() attempt 4 of 10: not in sync: resp=0x67
avrdude: stk500_getsync() attempt 5 of 10: not in sync: resp=0xc1
avrdude: stk500_getsync() attempt 6 of 10: not in sync: resp=0xc4
avrdude: stk500_getsync() attempt 7 of 10: not in sync: resp=0xc5
avrdude: stk500_getsync() attempt 8 of 10: not in sync: resp=0xa1
avrdude: stk500_getsync() attempt 9 of 10: not in sync: resp=0xcc
avrdude: stk500_getsync() attempt 10 of 10: not in sync: resp=0xe2
Error while burning bootloader."
Any help on how to use nodemcu to program attiny85 will be great
thanks

how did you prevent reset of the NodeMcu? try a different pin then io15 for reset of target

Hi thanks for answering, first thing I tries was GPIO5 with no success :(

how do you prevent auto-reset of the NodeMcu?

you mean by using a capacitor from RST to GND? I did try using a capacitor, although a 22uF one, did not work

Using  a 10 uF also did not work nor trying flashing the bootloader using the cmd

Modifications to the ArduinoISP.ino sketch
I made the following changes to the ArduinoISP.ino file it exists in IDE version 1.8.13, and uploaded it to the NodeMCU board.
In short, I commented out (by way of #if 0) the heartbeat, err, etc LED related stuff.  Not doing this causes the board to reset for reasons that would probably be apparent if I researched it, but I haven't and since I don't plan on using the LEDs and that you may not, I figured I would get this to you sooner.
I changed RESET to be SS which on NodeMCU is D8.
Why LED related code causes resets
... Out of curiosity I just went and looked at the ESP-12F and ESP8266EX datasheets.  GPIO7, GPIO8, GPIO9 all go to the ESP-12F's SPI flash (program storage), so ostensibly monkeying with them interferes with the modules ability to keep executing from the SPI flash.  They're not routed to NodeMCU pins, probably for that reason.  So there's the answer to that.
Differences
@@ -70,7 +70,7 @@
 // The standard pin configuration.
 #ifndef ARDUINO_HOODLOADER2

-#define RESET     10 // Use pin 10 to reset the target rather than SS
+#define RESET     SS // Use pin 10 to reset the target rather than SS
 #define LED_HB    9
 #define LED_ERR   8
 #define LED_PMODE 7
@@ -216,15 +216,17 @@

 #endif

 void setup() {

   SERIAL.begin(BAUDRATE);

+#if 0
   pinMode(LED_PMODE, OUTPUT);
   pulse(LED_PMODE, 2);
   pinMode(LED_ERR, OUTPUT);
   pulse(LED_ERR, 2);
   pinMode(LED_HB, OUTPUT);
   pulse(LED_HB, 2);
+#endif

 }

@@ -276,6 +278,7 @@
 }

 void loop(void) {
+#if 0
   // is pmode active?
   if (pmode) {
     digitalWrite(LED_PMODE, HIGH);
@@ -291,6 +294,7 @@

   // light the heartbeat LED
   heartbeat();
+#endif
   if (SERIAL.available()) {
     avrisp();
   }

NodeMCU to ATTiny85 ISP Wiring
The board is wired to the ATTiny85 as follows:
NODEMCU 3.3V -> ATTINY85 PIN 8
NODEMCU GND  -> ATTINY85 PIN 4
NODEMCU D5   -> ATTINY85 PIN 7
NODEMCU D6   -> ATTINY85 PIN 6
NODEMCU D7   -> ATTINY85 PIN 5
NODEMCU D8   -> ATTINY85 PIN 1

On the NodeMCU you'll find all 6 of these together on the right.
Verifying AVRDUDE functioning
avrdude -P /dev/ttyUSB0 -c stk500v1 -b 19200 -p attiny85

Reading | ################################################## | 100% 0.02s

avrdude: Device signature = 0x1e930b (probably t85)

avrdude: safemode: Fuses OK (E:FF, H:DF, L:71)

avrdude done.  Thank you.

I've been playing with this chip, so don't be surprised that I don't have the same fuse values you have.

Thanks a lot!
Commenting the LED parts in the code made the diffrence.

Good deal.  I'd considered just putting only that, but wanted to make it a little more complete.  To be clear, changing the pin definitions for the leds to non-problematic pins would also work.  I may edit it later to to suggest and, maybe add a picture of the wiring if I get around to making a clean picture.


text:
How do I Upload a Program via Serial Port to an Optiboot_X-Enabled TinyAVR-0/1 Microcontroller using the Command Line?
Background
In 2019, Microchip acquired Atmel and released several new AVR microcontrollers, including the Tiny-0 and Tiny-1 Series. On these mircocontrollers, traditional Atmel ICSP programming was not supported. Instead, they feature a new one-wire programming interface called Unified Programming and Debug Interface (UPDI). The new hardware also made existing TTL-serial bootloader programming obsolete. Thus, one must use a native UPDI programmer to work with these microcontrollers, such as pyupdi.
However, Optiboot's developers have subsquently developed a new version of the bootloader called Optiboot_X and implemented the STK500 programming protocol on these new microcontrollers, allowing one to program these microcontrollers using the traditional TTL-serial bootloader approach, and it appears that the Arduino community has already supported them for a while, with MegaCoreX and megaTinyCore, which was good news to me. Nevertheless, it seems that there's little resource beyond these prepackaged Arduino cores, in particular, there's almost no documentation on how to program them manually from the commandline.
What I've already done
I designed a custom AVR development board based on the Atmel ATTiny1604 microcontroller, which is a member of the new Tiny-0 family. Due to technical considerations, it must be programmed via the serial port using the bootloader similar to a traditional Arduino, not UPDI (UPDI is only used to burn the bootloader).
To achieve this goal, I installed the latest version of binutils, GCC and an experimental patch to avr-libc, so the compiler is able to generate code targeting my microcontroller. Then, I compiled my personal Optiboot_X bootloader.
$ git clone https://github.com/Optiboot/optiboot.git
$ cd optiboot/optiboot/bootloaders/optiboot
$ make -f Makefile.mega0 optiboot_attiny1604.hex UARTTX=A1 TIMEOUT=8 LED=A7 BAUD_RATE=57600 LED_START_FLASHES=10

Using Compiler at: /home/user/code/optiboot/optiboot/bootloaders/optiboot/avr-gcc
avr-gcc -g -Wall -Os -fno-split-wide-types -mrelax  -DWDTTIME=8  -DLED_START_FLASHES=10  -DLED=A7   -DUARTTX=A1 -DBAUD_RATE=57600       -Wl,-section-start=.text=0 -Wl,--section-start=.application=0x200 -Wl,--section-start=.version=0x1fe -Wl,--relax -nostartfiles -nostdlib  -mmcu=attiny1604 -o optiboot_attiny1604.elf optiboot_x.c
avr-size optiboot_attiny1604.elf
   text    data     bss     dec     hex filename
    494       9       0     503     1f7 optiboot_attiny1604.elf
avr-objdump -S  optiboot_attiny1604.elf > optiboot_attiny1604.lst
avr-objcopy -j .text -j .data -j .version --set-section-flags .version=alloc,load -O ihex optiboot_attiny1604.elf optiboot_attiny1604.hex

Then I uploaded the Optiboot_X bootloader to the ATTiny1604 microcontroller via UPDI, using pyupdi.
# set fuse BOOTEND
$ pyupdi -d tiny1604 -c /dev/ttyUSB0 -fs 8:0x02

# burn Optiboot_X
$ pyupdi -d tiny1604 -c /dev/ttyUSB0 -f optiboot_attiny1604.hex

# reset
$ pyupdi -d tiny1604 -c /dev/ttyUSB0 -r

After burning the Optiboot_X via UPDI, I was able to see 10 pulses during power-on at A7 on my oscilloscope, indicating that Optiboot_X was alive.
Note: Technically the installation is not complete yet. Since UPDI and /RESET share the same pin, UPDI must be permanently disabled via fuse to allow programming via bootloader, but it means a nonfunctional bootloader can brick the chip. I decided to manually reset the chip by power cycling the board for now.
Next, I wrote a test program.
$ cat blink.c

#define F_CPU 20000000UL
#include <avr/io.h>
#include <util/delay.h>

int main(void)
{
    PORTB.DIRSET = 0b00000001;

    while(1) {
        PORTB.OUTSET = 0b00000001;
        _delay_ms(500);
        PORTB.OUTCLR = 0b00000001;
        _delay_ms(500);
    }
}

And I compiled it.
$ make
avr-gcc -mmcu=attiny1604 -Wall -Os -o blink.elf blink.c
avr-objcopy -j .text -j .data -j .rodata -O ihex blink.elf blink.hex

Question
Now what? How do I upload blink.hex to the Optiboot_X on the microcontroller?
On a traditional Arduino, the command is something like...
$ avrdude -C/etc/avrdude/avrdude.conf -v -patmega328p \
  -carduino -P/dev/ttyUSB0 -b38400 -D -Uflash:w:blink.hex:i

But this is not an ATMega328P and there's nearly zero documentation on the web, I have a lot of questions and I'm not sure how to proceed.
To begin with, in man avrdude, there's no mention of any Tiny0 or Tiny1 devices. What should the -p argument be? Also, do I need to use a patched version of avrdude? Do I need a customized avrdude.conf? If so, where can I find them?

Since you're using optiboot avrdude shouldn't care what the chip is.

After poking around in the git repository for a while, I've solved the problem. To work with these new TinyAVR-0/1 microcontrollers, a new version of avrdude is needed. Since avrdude hasn't made a stable release yet, it's necessary to build a new avrdude from source from SVN.
$ svn co https://svn.savannah.nongnu.org/svn/avrdude/trunk avrdude
$ cd avrdude/avrdude
$ ./bootstrap
$ mkdir build && cd build
$ ../configure
$ make
$ make install

After installation, /usr/local/bin/avrdude and /usr/local/etc/avrdude.conf should be available. One can see that a bunch of new TinyAVR parts have been added...
$ avrdude -p?

Valid parts are:
  [...]
  t10      = ATtiny10
  t11      = ATtiny11
  t12      = ATtiny12
  t13      = ATtiny13
  t15      = ATtiny15
  t1604    = ATtiny1604
  t1606    = ATtiny1606
  t1607    = ATtiny1607
  t1614    = ATtiny1614
  t1616    = ATtiny1616
  t1617    = ATtiny1617
  t1634    = ATtiny1634
  t20      = ATtiny20
  t202     = ATtiny202
  t204     = ATtiny204
  t212     = ATtiny212
  t214     = ATtiny214
  t2313    = ATtiny2313
  t24      = ATtiny24
  t25      = ATtiny25
  t26      = ATtiny26
  t261     = ATtiny261
  t28      = ATtiny28
  t3214    = ATtiny3214
  t3216    = ATtiny3216
  t3217    = ATtiny3217
  t4       = ATtiny4
  t40      = ATtiny40
  t402     = ATtiny402
  t404     = ATtiny404
  t406     = ATtiny406
  t412     = ATtiny412
  t414     = ATtiny414
  t416     = ATtiny416
  t417     = ATtiny417
  t4313    = ATtiny4313
  t43u     = ATtiny43u
  t44      = ATtiny44
  t441     = ATtiny441
  t45      = ATtiny45
  t461     = ATtiny461
  t5       = ATtiny5
  t804     = ATtiny804
  t806     = ATtiny806
  t807     = ATtiny807
  t814     = ATtiny814
  t816     = ATtiny816
  t817     = ATtiny817
  t84      = ATtiny84
  t841     = ATtiny841
  t85      = ATtiny85
  t861     = ATtiny861
  t88      = ATtiny88
  t9       = ATtiny9
  [...]

To program the ATTiny1604, simply run...
$ avrdude -C/usr/local/etc/avrdude.conf -v -pt1604 \
  -carduino -P/dev/ttyUSB0 -b57600 -D -Uflash:w:blink.hex:i

Don't forget to modify the -b57600 argument to match the baud of your Optiboot_X build.
Lesson learned: When RTFM is impossible, use the source, Luke!
Potential Problems
avrdude: verification error; content mismatch
It's possible that avrdude successfully establishes communication with the board via the serial port, reads the correct device signature, then attempts to upload a program, but ultimately fails verification.
$ avrdude -v -pattiny1604 -carduino -P/dev/ttyUSB0 -b57600 -D -Uflash:w:blink.hex:i

Reading | ################################################## | 100% 0.00s

avrdude: Device signature = 0x1e9425 (probably t1604)
avrdude: reading input file "blink.hex"
avrdude: writing flash (204 bytes):

Writing | ################################################## | 100% 0.06s

avrdude: 204 bytes of flash written
avrdude: verifying flash memory against blink.hex:
avrdude: load data flash data from input file blink.hex:
avrdude: input file blink.hex contains 204 bytes
avrdude: reading on-chip flash data:

Reading | ################################################## | 100% 0.06s

avrdude: verifying ...
avrdude: verification error, first mismatch at byte 0x0000
         0x01 != 0x0c
avrdude: verification error; content mismatch

Solution: In TinyAVR 0/1, the bootloader is located at the beginning of the flash memory, occupies the first 512 bytes. When compiling the program to be uploaded via the bootloader, the correct 512-byte text section offset must be specified. Otherwise, avrdude will attempt to program from 0x00, which is impossible, because it's the location of the bootloader. Upon readback, instead of your program, avrdude reads the bootloader, which triggers the verification failure in question (it's worth noticing that 0x01, the first mismatched byte that triggers verification failure, is actually the first byte in the Optiboot_X binary code).
Instead of using...
avr-gcc -mmcu=attiny1604 -Wall -Os -o blink.elf blink.c

Recompile your program with `
avr-gcc -mmcu=attiny1604 -Wall -Os -o blink.elf blink.c \
-Wl,--section-start=.text=0x200

avr-objcopy -j .text -j .data -j .rodata -O ihex blink.elf blink.hex

And reupload it.
$ avrdude -v -pattiny1604 -carduino -P/dev/ttyUSB0 -b57600 -D -Uflash:w:blink.hex:i

avrdude: Device signature = 0x1e9425 (probably t1604)
avrdude: reading input file "blink.hex"
avrdude: writing flash (716 bytes):

Writing | ################################################## | 100% 0.00s

avrdude: 716 bytes of flash written
avrdude: verifying flash memory against blink.hex:
avrdude: load data flash data from input file blink.hex:
avrdude: input file blink.hex contains 716 bytes
avrdude: reading on-chip flash data:

Reading | ################################################## | 100% 0.00s

avrdude: verifying ...
avrdude: 716 bytes of flash verified

avrdude: safemode: Fuses OK (E:FF, H:FF, L:FF)

avrdude done.  Thank you.

avrdude: programmer type jtagice3_updi not found
It's possible that avrdude reports the following error...
/usr/bin/avrdude -C/usr/local/etc/avrdude.conf -v -pattiny1604 -carduino -P/dev/ttyUSB0 -b38400 -D -Uflash:w:blink.hex:i

avrdude: Version 6.3, compiled on Jul 24 2019 at 00:00:00
         Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
         Copyright (c) 2007-2014 Joerg Wunsch

         System wide configuration file is "/usr/local/etc/avrdude.conf"
avrdude: error at "/usr/local/etc/avrdude.conf:1091: programmer type jtagice3_updi not found
avrdude: error reading system wide configuration file "/usr/local/etc/avrdude.conf"

Solution: You are trying to run an old version of avrdude with a new configuration file. Make sure the avrdude executable you are running is actually the up-to-date version compiled from the upstream SVN repository.


text:
_delay_ms() is much slower than expected (by a factor of 6) on TinyAVR 0/1 (ATTiny1604)
I designed a custom AVR development board using the Atmel ATTiny1604 microcontroller. It belongs to the new Tiny-0 family, due to its recentness, some required changes to relevant toolchains have yet to be included into the stable version  (I prefer to use the original upstream toolchains instead of Atmel/Microchip's SDK). Thus, I compiled the latest versions of toolchains from source. They include...

AVR GCC 10.2.0

avr-libc, svn trunk, with patch avrxmega3-v10.diff applied

After I installed the toolchains, I wrote a LED blinking program to verify whether my toolchain was working properly. The program was built with avr-gcc -mmcu=attiny1604 -Wall -Os -o blink.elf blink.c -Wl,--section-start=.text=0x200 and uploaded via the Optiboot_X bootloader.
#define F_CPU 20000000UL
#include <avr/io.h>
#include <util/delay.h>

int main(void)
{
    PORTB.DIRSET = 0b00000001;

    while (1) {
        PORTB.OUTSET = 0b00000001;
        _delay_ms(500);
        PORTB.OUTCLR = 0b00000001;
        _delay_ms(500);
    }
}

However, I found that _delay_ms(500) doesn't work as expected. Instead of a 500-millisecond delay, the actual delay is closer to 3000 milliseconds as seen on the oscilloscope, it has been slowed down by a factor of 6.

I've double-checked my fuse settings.
$ pyupdi -d tiny1604 -c /dev/ttyUSB0 -fr
Device info: {'family': 'tinyAVR', 'nvm': 'P:0', 'ocd': 'D:0', 'osc': '3', 'device_id': '1E9425', 'device_rev': '0.0'}
Fuse:Value
0:0x00
1:0x00
2:0x02
3:0xFF
4:0x00
5:0xF6
6:0x07
7:0x00
8:0x02
9:0xFF
10:0xC5

I saw pyupdi reported that the fuse OSCCFG (No. 2) has been programmed to 0x02, which according to the datasheet, means "Run at 20 MHz with corresponding factory calibration". Why do I get incorrect delays even when the system clock is running at the correct speed? Is my toolchain broken?
Note: This is a question I already solved. But consider there are relatively few tutorials about the new TinyAVR 0/1 on the web, I posted the question and answer here to serve as a reference for the community.

Your toolchain is not broken. In the ATTiny804/1604 datasheet, page 77, it shows the CPU clock is divided from the 20/16 MHz oscillator by a prescaler (the ATTiny1614 datasheet shows the same clock prescaler in page 80. So it's a feature found in both tinyAVR 0/1 microcontrollers).

Source: Microchip ATTiny804/1604 datasheet, fair use.
The datasheet says...

10.3.3 Main Clock After Reset After any Reset, CLK_MAIN is provided by the 16/20 MHz Oscillator (OSC20M) and with a prescaler division factor of 6. Since the actual frequency of the OSC20M is determined by the Frequency Select bits (FREQSEL) of the Oscillator Configuration fuse (FUSE.OSCCFG), these frequencies are possible after Reset:

16 MHz ---> 2.66 MHz
20 MHz ---> 3.3 MHz

By default, the division factor is 6. It means the CPU is actually running at 3.333 MHz when the OSCCFG fuse is programmed to 20 MHz.
Solution
Use the correct F_CPU
If a slower CPU is not a problem to you, you can simply report the correct CPU frequency to the compiler by change #define F_CPU 20000000UL to #define F_CPU 3333333UL.
Or disable frequency division
Alternatively, you can disable the frequency division and run the CPU at its 20 MHz full speed.
#define F_CPU 20000000UL

int main(void)
{
    /* Set CPU clock to 20 MHz */
    _PROTECTED_WRITE(CLKCTRL_MCLKCTRLB, 0);

    /* your code */
}

But don't overclock the CPU
Nevertheless, you should note that 20 MHz operation is only guaranteed by Atmel at 4.5 V and above. If you are running the microcontroller at a lower voltage, such as 3.3 V, you are overclocking the CPU by putting it outside the safe operating area designated by Atmel. See datasheet page 473.

Source: Microchip ATTiny804/1604 datasheet, fair use.
Although an overclocked microcontroller will probably work, and in a hobby project, you are unlikely to see any issue. But still, at this point there is no guarantee of stability from the manufacturer. For example, the microcontroller is officially rated at 105°C, but an overclocked microcontroller may start crashing. Increased power consumption is also likely. The worst possible problem could be mysterious malfunction under certain rare conditions. Thus, if reliability and stability is important, you should not overclock the microcontroller.
At 3.3 V, given a 20 MHz system clock, the CPU should only operate at 10 MHz by setting the prescaler to 2x. And at 1.8 V, at 5 MHz with a 4x prescaler.
/* Set CPU clock to 10 MHz */
_PROTECTED_WRITE(CLKCTRL_MCLKCTRLB,
                 CLKCTRL_PDIV_2X_gc | CLKCTRL_PEN_bm);

/* Set CPU clock to 5 MHz */
_PROTECTED_WRITE(CLKCTRL_MCLKCTRLB,
                 CLKCTRL_PDIV_4X_gc | CLKCTRL_PEN_bm);


text:
Autolock transistor for powering Arduino
I have a portable project where I want to take care about batteries getting discharged.
Usually I just put a switch at the very beginning of my circuit that completely cuts off the electricity when switched off. The problem with this approach is that if you forget to switch it off your batteries will discharge.
So I was thinking about an approach that after some inactivity time cuts off the circuit (I want to completely cut off the electricity to minimize power consumption, so I'm not interested in sleeping modes or similar approaches).
So my approach consist in changing a switch for a regular push button that   enables the circuit when pushed, and then one of the arduino pins is used to lock the transistor until a function times out and the pin gets to a low voltage (see image)
In the arduino code I can just test a simple program that keeps the circuit closed for 10 seconds and then switches it off.
setup() {
    pinMode(3,OUTPUT);
    digitalWrite(3,HIGH);
    delay(10000);
    digitalWrite(3,LOW);
}

loop() {
}

For the transistor part I'm not sure what to use. I was thinking about using an motor driver L298 (which should work and also accepts some load for other electronics that I might have in the project)
However this looks like something that should already exist (either in a shield or maybe integrated in some Arduino variant).
Does anybody have experience with such an approach or a suggestion on any standalone transistor that would also do the job?
Any help is appreciated :)
.

Search "transistor latch circuits" for a lot of articles about them including how-to. From there you can decide whether to build or buy.

from the look of it, most n-chan mosfets would work as expected. i would add a diode to the left "rail"

Here is a mock-up of what I usually do.

simulate this circuit – Schematic created using CircuitLab
Keep in mind that the resistors are just an example value: you'll have to make some calculations.
Now, M1 is a PMOS, while M2 is an NMOS. Both MOSFETs should be able to turn on and off with the voltages you can supply them (so look at their Vgs curves). Moreover the M1 mos will be the one where all the supply current will run, so you'll have to choose it wisely. The M2 mos will only have to supply a small current, so the smallest one is fine. Beware that if the Vin voltage is greater than the maximum Vgs voltage of M1 you'll have to add a resistor between M1 gate and M2 drain to form a voltage divider with R1.
The R4 and D1 are used if you want to detect a SW1 push (for instance to turn off the device). If you don't need this feature, remove them both.
The circuit works this way: when you push the button, a voltage (for instance 5V - 0.6V of D1) will come to the arduino Vcc. The arduino then should immediately bring up the pin. This will turn on M2, which in turn switches on the M1 transistor, thus bypassing the switch. When you remove it, the arduino stays powered.
When the arduino decides that it should turn off (either because you pressed the button again, or because it timed out, or who knows) it executes two instructions: one to pull down the pin and the other is while(1). This prevents it to continue executing the program. The M2 transistor shuts down, the M1 gate floats to Vin and so it shuts down too.
You can find the transistor as discrete componetns (sometimes also in the same SOIC-8 package. Usually I use big pMOS (e.g. IRF9310 in SOIC8) and smaller nMOS (usually in SOT-23 case). I do this because I can easily solder them also on perfboards (SOIC8 single transistors have a lot of redundancy for pins, while SOT-23 ones can be mounted easily on 3 pads).

If you would like an out-of-the-box solution, the Pololu Pushbutton Power Switch is a lovely piece of hardware that lets the device turn itself off :)
Update: Adafruit also released a "Low Power Timer Breakout" that allows a device to be turned on automatically from 1s-2hr intervals, and then disable the power supply from the device once each run is done.
If you need less often than 2 hr intervals, you could increment a number in EEPROM in setup() each run and immediately re-enter sleep if the number doesn't match your desired value.


text:
Knowing if ESP32 wakes up itself or manually
I have a project where I put an ESP32 to deep sleep for a certain amount of time, eg: 1h
To be able to self-awaken a cable must be connected from GPIO 16 to the reset pin, so basically the ESP pulls down pin 16 and causes itself to reset.
I also need the possibility to manually waken up the ESP, so in parallel to this cable I connect a button to GND, so I can manually reset the ESP and waken it up.
However I need to be able to tell if the ESP has awaken itself because one hour has passed or if it has been manually awaken.
I cannot connect the ESP to a internet time provider to check the time, so my first though wasto connect the button also to an input and read it when the ESP starts.
However the ESP won't start until the button forcing RST low is released and then it's too late to read it and see if it was pressed.
Is there a way that I can tell if the ESP was manually reset or if it woke up by itself?

I think you're getting confused between the ESP32 and the ESP8266. There is no need to connect GPIO16 to reset on the ESP32.
Instead the ESP32 has the "ULP" - Ultra Low-power Processor in it (essentially the RTC processor) which is what sends wakeup signals to the ESP32 cores. It is this which wakes the system up after an hour.
The ULP can also trigger a wakeup from other sources - most often used to wake up from an external signal, such as your button. But this only works if that signal is connected to one of the RTC input pins (GPIOs 34 to 39), or certain interrupt enabled pins (you can read more about what can wake the system up here).
Once a wakeup has happened you can then query the ULP to find out why it woke the ESP32 up using the esp_sleep_get_wakeup_cause() function.

the esp8266 has the RTC too, only there is some design bug and it can't wakeup internally. the io 16 connection to reset is a workaround

Another reason to not bother with the esp8266 and go straight for the ESP32...

Thanks. looks like that's what I needed.


text:
Managing 80 ~ 90 accelerometers with Arduino
If one were to want to keep track of data from 80 - 90 accelerometers using arduino, what would be the best way to go about this challenge?

Please specify what data rate do you need, distance between accelerometers, are you open to using more than one arduino?

1) Use the I2C address select inputs as an "enable".  If you run out of I/Os before running out of bus time, drive the enables from an I/O expandander. If your accelerometers are SPI, drive or use the expander to drive the chip selects.
2) Use a tree of slave MCUs (Arduino or otherwise) reading a number of accelerometers, extracting and batching the useful data, and reporting only that upstream to a master.  Probably use whichever of I2C or SPI your accelerometers are not using (SPI can be much faster, so hopefully that).
Some accelerometer / gyro parts have an on-board processor which you may be able to program to do some of the data extraction for you.
You could also consider using an FPGA to collect the data.  A commonly available one with enough I/O pins to have a dedicated connection to each accelerometer (and so read them all in parallel) would probably also have the internal resources to implement an Arduino-class soft core processor, if not better.


text:
Over voltage protection for Arduino
If an external voltage of 7 volts is applied to the external voltage input on the Arduino and the power from the USB port remains connected, is there a protective circuit that will protect the Arduino?  Thank you.

Protect it from what?

yes there is. power will be drained from external source(altough 7 volts is around the limit and arduino may switch to usb power) and arduino will still operate at 5v, same as usb. in any case your arduino and usb will be safe.

The opamp that turns off the mosfet, to disable USB-Vcc, is set to 6.6Volt.

glad to help. Generally speaking, if a given answer satisfies you then you should mark it as accepted. See also faq about accepting answers. Thank you


text:
Automatic/manual door lock with servo
I'm building an automatic door lock, which is moved by a servo ( this one ). However, I want to still make it possible to open the lock manually, but it's not possible if the servo is attached to the lock mechanism.
Do you have ideas on how to go around this problem?
Here's a diagram of the lock mechanism

Can you give some more detail about how the lock is intended to function? We may be able to come up with some hitherto un-thought of solution, but we need to know how the whole mechanism will function to be able to visualise it better.

@Majenko I've edited the question with a diagram of the lock mechanism

Excellent, that's exactly what we need to see.

I'm voting to close this question as off-topic because This question belongs on another site in the Stack Exchange network -- eg
Robotics Stackexchange

Ok my bad, but will it still be visible? Other people could find this thread useful.

Jonathan, I doubt the question will get closed; it takes 5 such votes (or a moderator) to close a question.  But it might get migrated to  Robotics Stackexchange, which is as visible as but less popular than Arduino SE.  Note, closed questions remain visible, but are not eligible for new answers.

Robotics Stack Exchange declined the migration.

So it's actually the worm gear that is causing your problem, since that can't be reverse driven by the cogs.
The simplest option, I think, would be to have the middle cog normally separated from the worm gear and only re-engage it when you need to drive the mechanism with the servo.  You could maybe use a second servo to move it into the right place, or maybe a solenoid, or something along those lines. Have it slide along a short track or slot with a spring to ensure it disengages when the solenoid is released.

Do you think it would be simpler/better to change the servo with a DC motor?

If you still have the worm gear in there you'll still be in the same boat. Most electronic locks work by releasing the other end of the tennon from the mortice instead of retracting it - it's simpler that way.

but with a DC motor rather than a servo, you can rotate it manually without problem. The only thing to manage is the current generated by this free rotation.
But, if we stay with the servo, which of the 2nd servo or a sollenoid do you think will be best (if you have an opinion) ? In terms of complexity to implement and also constancy.

A solenoid is the normal preferred option. You sometimes see clutch gears that allow the outer teeth to rotate independently of the central axis, which would be in place of the lock spindle cog - but those are expensive and generally custom designed. You see them in laser printers quite often for the paper feed.

You sometimes see ratchet clutch cogs too, where if you rotate the teeth in one direction the turn the central spindle, but in the other direction they don't engage with the spindle - and the spindle can rotate separately too. Again complex and expensive...

Thanks a lot for all your insights. I'd vote up your answer but I don't have the privilege on the Arduino exchange!

@Jonathan That will come with time :)


text:
Why is there a clock in my arduino?
Of course I know it is usefull to control the time of a delay, but any other use?
With a 16Mhz clock, each line of my program will take 1/16000000 second, right?
even a very very big line will only take 1/16000000 of a second ?
With a 8MHz clock, each line will take the double of the time, right?
So the whole "main loop"  will take the double time too, right?

You are confusing between C instructions and machine (assembly) instructions. But even if you wrote directly in assembly, you could find good use of that because the program is NOT linear. I mean, interrupts, as the name suggests, interrupt the normal code flow by going at another instruction and then resuming. So maybe between one line and the next one it is forced to execute the ISR, which may be very long

If you clock your chip at eight millihertz, even the simplest line of code will take forever. I suggest you use a clock in the megahertz range (MHz).

The number of cycles needed to execute each machine instruction is stated in the Instruction Set Manual.

Damn I should go to sleep ;), edited thanks

Why is there a clock in my arduino?

Because that is how computers and microcontrollers, etc, work.

With a 16mhz clock, each line of my program will take 1/16000000 second, right?

No.

even a very very big line will only take 1/16000000 of a second ?

No.
The clock defines at what speed the machine code instructions are fetched from memory and executed. Most instructions take 1 clock cycle, but some take more.
One line of C code may be compiled into any number of assembly instructions, which then get converted into machine code (raw numbers).  That could be anywhere from 1 assembly instruction to thousands of assembly instructions, depending on what the line does.

With a 8mhz clock, each line will take the double of the time, right? So the whole "main loop" will take the double time too, right?

Every operation in the chip is governed by the clock. If the clock is half the speed the chip is running at half the speed, so every operation will take twice as long, yes.

also, interrupts.

Minor nitpick: Should be "...anywhere from 0 assembly instructions...", even without optimizer, but even more so after optimization.

Don't confuse the poor boy. He is having a hard enough time as it is.

@Majenko: the confusion is a necessity. IT is hard.

@intelfx "IT"? This is programming, not IT....

@BalinKingOfMoria: FYI. systems programming is a strict subset of IT :)

@intelfx Looked it up, you're right... Learn something new every day! Thanks :)

Not answered in @Majenko's post: Yes, with a 8MHz clock, each line will take the double of the time. Unless the line waits for something that is not clock driven - e.g. external input.
In addition to @Majenko's answer, a CPU has a clock to ensure the instructions are complete, before the next step starts. A CPU is made out of lots of transistors (I found a reference that indicated the AtMega was in the range of low millions, give-or-take an order of magnitude).
During a cycle, the electricity flows through the chip, turning transistors on/off, the results of which will turn more transistors on/off, and so forth down the line. While this is happening, some parts of the chip have a "wrong" value - you can think of this as being half-way through a calculation (you've added the one's column and the 10s column, and are about to start on the 100s column). You don't want this to affect the outside world, so (for example) your output pins are latched - held at whatever value they are - until the instruction is complete. How long it takes to complete an instruction varies, but the manufacturer works out the slowest instruction under the worst circumstances.
For the AtMega (which is the chip on the Arduino), Atmel (who designed the chip) has declared this is 1/20,000,000 of a second - this is 20MHz.
Note that not all microprocessors run all their instructions at 1 instruction per cycle - some instructions might take 1, or 2, or 10 cycles. Pipelining makes things even more complicated - a processor might do some of the work (e.g. fetch the next instruction) in one cycle, execute it in the next - but while it is executing instruction 1, it can also fetch the next instruction. To do this, it might need to take a guess at what instruction comes next (in the case of the machine-code equivalent of a "goto" - such is used for loops), and if it guesses wrong, it has to cope with that; throw away the instruction it retrieved and retrieve the next one, losing a cycle.
The Wikipedia page on instruction pipelining shows an example of a RISC chip pipelining in 5 stages - instruction fetch, instruction decode, execute, memory access, and write-back. So, you can have 5 instructions at some stage of execution, overlapping. Until the "writeback" phase, the instructions have no real effect. You can think of this as an assembly line - it takes 7 minutes to put a widget together, but it can be broken down into 5 stages, the longest stage taking 2 minutes. Once every two minutes, each partly completed widget is moved by the assembly line to the next station. You get one widget out every two minutes - The "clock" can only tick as fast as the slowest step. If you push the widget out any faster, the "bottleneck" will get more and more widgets queued up.

The AVR has a very shallow pipeline: only fetch and execute. Then, conditional jumps take either one cycle (jump not taken) or two cycles (jump taken).

Additional complication: cache misses.

There are many things I did not mention: cache (of any type), multi-threading, multi-core... I probably went into too much depth in my post already.


text:
HID multiCLASS RFID reader all Mifare to Wiegand 32bit
I'm using an Arduino Uno to read from a "HID multiCLASS (RP40CKPNN) reader", which is a stand-alone reader that reads cards and returns a number of bits via Weigand Data0/Data1 protocol.  The "multiCLASS" readers can read both 125HZ PROX tags, and 13.57MHz mifare tags.
I have it reading and decoding 125HZ (multiple-PROX format) tags of various bit-lengths just fine, but when the reader is presented with a 13MHz card (specifically Mifare cards) the reader decodes the CSR/UID of ALL Mifare cards to 32bits.  The Mifare cards come in two types, Classic (that use a 4byte UID), and Ultra (that use a 7byte UID), so I would expect 32bits for the Classic cards, and 56bits for the Ultra, but I only ever get back 32bits.
The reader's data-sheets specifically calls out that for mifare tags it should return a 32bit or 56bit CSR value based on the serial number of the card, but I've looked through lots of HID literature on this reader, and I can't find any specifics on how to change/modify its configuration.
Does anyone have any experience with these readers, and is there some trick to changing the configuration so that it returns more bits for Mifare cards?

Can't you just reverse the order of the bytes? This sounds like an "endian" issue of your library. Please provide a link to the library.

Were you possibly looking at my other question?  That was a question about reversing the order of the bytes (which is how I was finally able to to get the correct 4byte UID).  This question is specific to this readers.  It provides me only 32bits for both mifare classic (4byte UID) and mifare ultra (7byte UID).  I would expect it to return 32bits for mifare classic and 56bits for mifare ultra, or am I missing something completely?

it looks like it decodes the CSR/UID of all Mifare cards - what are the words "it" referring to here? Please provide a link to the card in question, the library in question, and your code. In what way does "it" look like it is doing "it"?

IT, as I state in my questions is an: "HID multiCLASS (RP40CKPNN) reader" http://www.hidglobal.com/products/readers/iclass-se/smart-card-readers. It uses a Wiegand interface to transfer information to my Arduino.  I've reviewed all of the information I can find on this specific reader, and from what I reading between the lines it looks like some of the configuration is done via proprietary cards, but I can find not further information on that.

To be clear, this is not one of the breakout board readers such as the PN522, or Paralax serial reader, etc.  It's a 3rd party "stand alone" reader that returns a set number of bits via Wiegand Data0/Data1 interface to the Arduino.  I'm just trying to find out if anyone has any specific experience with these readers.  THANKS!

I haven't, so I can't help you with that. You may help others to answer you if you provide your code. For example, on the Arduino side can you demonstrate that you are reading 56 bits?

It's not really an issue of code...  The reader itself is only sending 32bits of data for both Mifare classic and ultra.  I would expect 32bits for classic (4byte UID), and 56bits for ultra (7byte uid), but for both types of tags I only get back 32bits.  The question is more specific to if there's any trick I can use to configure the reader to send more bits for these card types. The data-sheets for the readers specifically mention that ability but not HOW to configure it. :)  Thanks for the effort.

Only Mifare classic is mentioned in its 2-page datasheet. Provide the exact link to the datasheet and also your code, since all config must be done with code after all

Actually the config is not determined by code for this reader, as it turns out configuration changes for these readers are done via specific cards that you obtain from HID Global.  The reader reads the cards, and then changes its configuration.

For this specific reader, communication is only one way, from the reader to the Arduino via Weigand protocol.  Because of this, changes to the configuration for these readers is handled by proprietary RFID cards obtained from HID Global. The reader reads the card, and changes its configuration accordingly.  I was able to reach out to HID Global technical support and they are sending me a card that will change the configuration to output 56bit CSN/CSR/UID for mifare cards (which will cover the 7byte UID of mifare ultra).
Thanks for the comments that helped me work this through.


text:
arrange vector in descending order
im trying to arrange the vector in descending order but its not happening..
int fibonacci[15]={0, 1};
int a=0;

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

  for (int i=0; i<=14; i++) //loop to create the array
  {
    fibonacci[i+2]=(fibonacci[i])+(fibonacci[i+1]);
  }

  //Now arrange in descending order
  for (int i=0; i<16; i++)
  {
    for (int j=i+1; j<16; j++)
    {
      if (fibonacci[i]>fibonacci[j])
      {
        a=fibonacci[i]; //mux number
        fibonacci[i]=fibonacci[j];
        fibonacci[j]=a;
      }
    }
  }

  for (int k=0; k<16; k++)
  {
    Serial.println(fibonacci[k]);
  }
}

void loop() {
}

14 is the last i index, but you are still reading from i+1 and writing to i+2. You should fix your bounds.

I guess that what you want is a descending sort algorithm, but in the case of Fibonacci numbers you can take advantage that they are already sorted at the beginning. Here are different strategies that you can try :
/*
  SORTING IN DESCENDING ORDER
*/

const int nbElem = 15; // 24 max
int fibonacci[ nbElem ] = { 0, 1 };

void createFibonacciArray( int inputArray[], int arraySize )
{
  fibonacci[ 0 ] = 0;
  fibonacci[ 1 ] = 1;
  for( int i=0; i<nbElem-2; i++ )
    fibonacci[ i+2 ] = fibonacci[ i ] + fibonacci[ i+1 ];
}

void displayArray( int inputArray[], int arraySize )
{
  for( int i=0; i<arraySize; i++ )
    Serial.println( inputArray[ i ] );
}

void displayArrayReverse( int inputArray[], int arraySize )
{
  for( int i=arraySize-1; i>=0; i-- )
    Serial.println( inputArray[ i ] );
}

void reverseArray( int inputArray[], int arraySize )
{
  for( int i=0; i<nbElem/2; i++ )
  {
    int fTemp = fibonacci[ i ];
    fibonacci[ i ] = fibonacci[ nbElem-i-1 ];
    fibonacci[ nbElem-i-1 ] = fTemp;
  }
}

void inverseBubbleSort( int inputArray[], int arraySize )
{
  for( int i=0; i<arraySize-1; i++ )
  {
    for( int j=0; j<arraySize-1-i; j++ )
    {
      if( inputArray[ j ] < inputArray[ j+1 ] )
      {
        int temp = inputArray[ j+1 ];
        inputArray[ j+1 ] = inputArray[ j ];
        inputArray[ j ] = temp;
      }
    }
  }
}

void bubbleSort( int inputArray[], int arraySize )
{
  for( int i=0; i<arraySize-1; i++ )
  {
    for( int j=0; j<arraySize-1-i; j++ )
    {
      if( inputArray[ j ] > inputArray[ j+1 ] )
      {
        int temp = inputArray[ j+1 ];
        inputArray[ j+1 ] = inputArray[ j ];
        inputArray[ j ] = temp;
      }
    }
  }
}

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

  // Create and display Fibonacci array
  createFibonacciArray( fibonacci, nbElem );
  Serial.print( "\n\nFIBONACCI ARRAY\n" );
  Serial.print( "===============\n" );
  displayArray( fibonacci, nbElem );

  // Solution 1: Display array starting from the end
  Serial.print( "\n\nFIBONACCI ARRAY STARTING FROM THE END\n" );
  Serial.print( "=====================================\n" );
  displayArrayReverse( fibonacci, nbElem );

  // Solution 2: Reverse array
  reverseArray( fibonacci, nbElem );
  Serial.print( "\n\nFIBONACCI REVERSED ARRAY\n" );
  Serial.print( "========================\n" );
  displayArray( fibonacci, nbElem );

  // Solution 3: Inverse bubble sort array
  createFibonacciArray( fibonacci, nbElem );
  inverseBubbleSort( fibonacci, nbElem );
  Serial.print( "\n\nFIBONACCI SORTED IN DESCENDED ORDER WITH BUBBLE SORT\n" );
  Serial.print( "====================================================\n" );
  displayArray( fibonacci, nbElem );

  // Ascending order sort array
  bubbleSort( fibonacci, nbElem );
  Serial.print( "\n\nFIBONACCI SORTED WITH BUBBLE SORT\n" );
  Serial.print( "=================================\n" );
  displayArray( fibonacci, nbElem );
}

void loop()
{}

You can use it using bubble sort algorithm (which is most simple but inefficient)
int fibonacci[15]={0, 1};
int a=0;

int arraysize=2; // variable to store size or array

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

  for (int i=0; i<=14; i++) //loop to create the array
  {
    fibonacci[i+2]=(fibonacci[i])+(fibonacci[i+1]);
    arraysize++;
  }

  //Now arrange in descending order using bubble sort
  for (int i=0; i<arraysize; i++)
  {
    for (int j=0; j<arraysize-1; j++)
    {
      if (fibonacci[j]<fibonacci[j+1])
      {
        a=fibonacci[j+1]; //max number
        fibonacci[j+1]=fibonacci[j];
        fibonacci[j]=a;
      }
    }
  }
  //------------------------------------------------

  for (int k=0; k<16; k++)
  {
    Serial.println(fibonacci[k]);
  }
}


text:
Arduino Due: Interrupt-based ADC hangs processing
I am trying to build an oscilloscope using an Arduino Due and an LCD. I have the LCD running perfectly and started working on using the ADC peripheral to sample signals. Here's what I have so far:
#define SAMPLE_BUFFER_SIZE 800
volatile int sample_buffer[SAMPLE_BUFFER_SIZE];
volatile bool sample_buffer_full = 0;
volatile int sample_buffer_idx = 0;

void adcm_init() {
    pmc_enable_periph_clk(ID_ADC); // To use peripheral, we must enable clock distributon to it
    adc_init(ADC, SystemCoreClock, ADC_FREQ_MAX, ADC_STARTUP_FAST); // initialize, set maximum posibble speed
    adc_disable_interrupt(ADC, 0xFFFFFFFF);
    adc_set_resolution(ADC, ADC_12_BITS);
    adc_configure_power_save(ADC, 0, 0); // Disable sleep
    adc_configure_timing(ADC, 0, ADC_SETTLING_TIME_3, 1); // Set timings - standard values
    adc_set_bias_current(ADC, 1); // Bias current - maximum performance over current consumption
    adc_stop_sequencer(ADC); // not using it
    adc_disable_tag(ADC); // it has to do with sequencer, not using it
    adc_disable_ts(ADC); // deisable temperature sensor
    adc_disable_channel_differential_input(ADC, ADC_CHANNEL_7);
    adc_configure_trigger(ADC, ADC_TRIG_SW, 1); // triggering from software, freerunning mode
    adc_disable_all_channel(ADC);
    adc_enable_channel(ADC, ADC_CHANNEL_7); // just one channel enabled
    adc_enable_interrupt(ADC, ADC_IER_DRDY);            // Data Ready Interrupt Enable
    NVIC_EnableIRQ(ADC_IRQn);
    adc_start(ADC);
}

void ADC_Handler(void)  {
    if (!sample_buffer_full) {

        if ((adc_get_status(ADC) & ADC_ISR_DRDY) == ADC_ISR_DRDY) {

            sample_buffer[sample_buffer_idx] = adc_get_latest_value(ADC);
            sample_buffer_idx++;

            if (sample_buffer_idx == SAMPLE_BUFFER_SIZE) {
                sample_buffer_full = 1;
                sample_buffer_idx = 0;
            }
        }
    }
}

void setup()
{
    adcm_init();
    Serial.begin(115200);
}

void loop() {
    Serial.print("Loop\n");
    if (sample_buffer_full) {
        for (int i = 0; i < SAMPLE_BUFFER_SIZE; i++) {
            Serial.print(sample_buffer[i]);
            Serial.print(" ");
        }
        Serial.print("\n");
        sample_buffer_full = 0;
    }
}

This was copied and slightly modified from somewhere on the internet (can't remember where, though). I have also studied the docs and this code seems to make perfect sense and it should work.
The idea is for the sampling to be interrupt-based. However, if I set the ADC to freerunning mode and enable interrupts, it just gives up and stops working.
What I mean by that is: on my serial monitor, after pressing reset, all I see are 2 lines saying "Loop" and it just stops there. Normally it should print "Loop" indefinitely, and also print ADC values from time to time.
If I disable interrupts, "Loop" is printed indefinitely, but of course no values are shown. If I disable free-running mode, "Loop" is printed and no values are shown unless the buffer size is 1, in which case the same value is printed over and over (as expected, in that case the interrupt runs only once, right at the beginning).
The CPU clock freq. is 84Mhz, I'm going for the fastest I can get out of the ADC, so a sample is taken (and an interrupt is fired) every 1Mhz. That means 84 clock cycles per interrupt. Don't know for sure if that is enough for the rest of the program to work, but my gut tells me that's not a problem. Besides, I tried with a lower ADC clock value and it still didn't work.
Any ideas? I'm really at a loss here...

You only want two samples?

@NickGammon No, of course not. I'd like hundreds of them. Sorry, that was just me testing the code (edited question and changed sample number to 800).

I'm no Due expert, but where do you link ADC_Handler as being the interrupt handler for those interrupts?

I've spotted a few threads that mention that handler but they have it inside extern "C" declarations.

@NickGammon It's defined in the ATMEL source code as void ADC_Handler        ( void ) __attribute__ ((weak, alias("Dummy_Handler")));

Try making it extern "C" - from what I have just read Dummy_Handler consists of: while(1) { }

In your interrupt handler, ADC_Handler(), you set sample_buffer_full when the buffer is full.  I don't see anywhere in the code where  sample_buffer_full ever gets reset (cleared) once it's been set.
While sample_buffer_full is set, it disables the body of the interrupt handler – ie, the handler's structure is
if (!sample_buffer_full) { ...body of handler... }

– and in particular, prevents adc_get_latest_value(ADC); from occurring.  The source code of adc_get_latest_value(); is like
uint32_t adc_get_latest_value(const Adc *p_adc) {
  return p_adc->ADC_LCDR;
}

which accesses the ADC data register.  According to section 43.6.4 Conversion Results on page 1322 of the data sheet, Atmel-11057-32-bit-Cortex-M3-Microcontroller-SAM3X-SAM3A_Datasheet.pdf,

The channel EOC bit in the Status Register (ADC_SR) is set and the DRDY is set. In the case of a connected PDC channel, DRDY rising triggers a data transfer request. In any case, either EOC and DRDY can trigger an
  interrupt.
Reading one of the ADC_CDR registers clears the corresponding EOC bit. Reading ADC_LCDR clears the DRDY bit and EOC bit corresponding to the last converted channel.

It appears to me that your code enables interrupts, fills a buffer, sets sample_buffer_full, then spins in ADC_Handler().  That is, repeatedly executes ADC_Handler() without clearing the EOC bit.
Note, for  oscilloscope applications with a Due, I suggest using DMA buffers instead of one interrupt per conversion.  See thread #137635, speed of analogRead, in forum.arduino.cc for DMA code to read one or two analog channels on a Due at one sample per microsecond.  Also see edaboard.com/thread283843 and forum.arduino.cc #186169
Edit note: Although sample_buffer_full does get reset, that reset happens after a time-consuming for-loop.  Whether it takes some hundreds of microseconds or a few milliseconds, the for-loop is enough of a delay that at least one more conversion and interrupt will occur before sample_buffer_full gets cleared.  One unhandled conversion is enough to lock up the interrupt handler.  Here are some alternative approaches to consider:
• Use a circular buffer, and never stop filling it.  This is ok if you are only interested in the most recent data, rather than a complete waveform record.
• Set or reset sample_buffer_full as now; and remove the initial if test from the handler.  Instead, put an if before sample_buffer_idx++;, to not increment if the buffer is full.
• Turn off ADC's freerun mode.  This is a reasonable thing to do when not taking data.
• Turn off ADC's interrupt when not taking data.  Also reasonable.
• Use multiple buffers.  Reasonable, but by itself doesn't avoid the problem.
• Read the latest value every time the handler executes [for example, say int datum = adc_get_latest_value(ADC); as the first statement in the handler] and then only store that value in certain cases.  An easy and effective way to avoid problem.

Sorry, I copied my code wrong. There should be a line sample_buffer_full = 0; inside my loop code (I've edited my question). The code with that line does not work.

Also, many thanks for the DMA buffers suggestion. I'd already seen some code examples use that, but I was trying to get it to work this way first before moving on to other more advanced options.

Ohh! I see! Well caught, thank you very much. That might just explain the problem, yes...

Yes, I tried your last suggestion and it works perfectly, which means your answer was spot on. You certainly deserve an upvote and an accepted answer. Thank you very much!


text:
Arduino Due: enable reentrant interrupt
I'm using the TC3 interrupt on my Arduino Due to run some code periodically, like this:
void TC3_Handler() {
  TC_GetStatus(TC1, 0); // Remove interrupt flag
  // My code...
}

However, as I've found out, the CPU will not service the same interrupt a second time while the interrupt is running. By editing the priorities of each interrupt source, it's possible for a higher priority interrupt to preempt and run over this interrupt (so nested interrupts are possible), but priority manipulation alone does not allow reentrant interrupts.
I'd like to know if there is any way to make this interrupt reentrant.

In your notion about the meaning of Reentrant interrupt, you write:

interrupt A can preempt handling of interrupt A; interrupt A's handler can be active concurrently with itself

I. The first half of the notion correctly states a condition that might trigger re-entrance of an ISR (interrupt service routine).  Note, an ISR that allows re-entrance might or might not be called reentrant: an ISR's code is reentrant if it performs correctly when it is re-entered.
On most processors that use a single stack, code will be reentrant if it has no side effects and does not access variables that are not in its stack frame.  It might be reentrant even if it does have side effects or accesses non-local variables, if its actions are idempotent or if some proper concurrency protocol is implemented.

II. The second half of the notion is misleadingly stated:  true concurrency does not occur on a single-thread-of-execution processor.  However, time sharing and task overlap may occur on such a processor via task switching using either preemptive or cooperative multitasking.
As explained in the next paragraph, to the best of my knowledge preemptive serial multitasking is what would happen if you re-enable the interrupt system within an ISR.
Let's suppose ISR A is written in a reentrant fashion, and that it clears the interrupt A interrupt flag early in its processing, and enables interrupts so more A interrupts can occur and be processed.  Also suppose three interrupt A's occur in quick succession (more precisely, quickly enough that processing of one does not complete before another comes along, but not so quickly that the A flag has not been cleared, which would cause loss of an A interrupt) followed by a hiatus.  In this case, the first interrupt A occurs; the ISR entry prologue creates a stack frame for the ISR code to use, then saves a number of registers, then begins executing user code, which we suppose turns interrupts back on.  After a bit the second interrupt A occurs.  ISR entry prologue creates stack frame and saves registers.  User code enables interrupts.  Third interrupt A occurs.  ISR entry prologue creates stack frame and saves registers.  User code enables interrupts.  As we've posited a hiatus, no more A interrupts occur for a while.  So processing of interrupt 3 proceeds and finishes.  The ISR epilogue reloads registers, clears the stack frame, and returns from interrupt, restoring the previous interrupt state.  Then processing of interrupt 2 proceeds, finishes, reloads registers, returns from interrupt.  Then processing of interrupt 1 proceeds, finishes, reloads registers, returns from interrupt.  Then loop() [or whatever is running in the main thread of execution] resumes its work.
As you can see from this example, interrupt processing will occur in a LIFO (last-in, first-out) order if an ISR simply accommodates re-entrance.  If that is what you want, fine.  If, however, you want interrupt processing to complete in order; want to do lengthy processing  while avoiding interrupt misses; and want to process in a secondary thread of execution, ie, a callback-like system, then the thing to do is have the ISR make a queue entry (in a static or heap-based circular queue) each time it starts; return from interrupt if it was re-entered; and process queue entries until the queue is empty, using atomic operations when changing queue pointers.

Edit 2:  In §10.20.9.1 of the SAM3x/SAM3A datasheet, “Hardware and software control of interrupts”, we find

A peripheral interrupt becomes pending for one of the following reasons:

• the NVIC detects that the interrupt signal is HIGH and the interrupt is not active
    ...

A pending interrupt remains pending until one of the following:

• The processor enters the ISR for the interrupt. This changes the state of the interrupt from pending to active.  Then:

• For a level-sensitive interrupt, when the processor returns from the ISR, the NVIC samples the interrupt signal. If the signal is asserted, the state of the interrupt changes to pending, [...] Otherwise, the state of the interrupt changes to inactive.
       • If the interrupt signal is not pulsed while the processor is in the ISR, when the processor returns from the ISR the state of the interrupt changes to inactive.

• Software writes to the corresponding interrupt clear-pending register bit.
    ...

[Emphasis added]
This suggests that although the ISR for a given interrupt source on a SAM3x/SAM3A system can be interrupted by a higher-priority source, a given source can not re-interrupt until “the processor returns from the ISR”.  Without some research or testing, it isn't clear to me if that is correct, and whether software can simulate a return from ISR without actually returning.  Setting that possibility aside, here is a workaround to allow interrupt A to recur:
Set the interrupt priority of A fairly high, say level z.  Set up several selected SGI's (software generated interrupts) at levels p, q, r ..., all lower-priority than z.  Initialize an A level variable to point to the least-priority SGI ISR among those selected.  Upon any A interrupt, the A ISR issues an A level SGI, saves any data that SGI ISR needs, updates A level to next-higher-priority SGI [if possible], and returns from interrupt.  This re-enables A interrupts and allows the most recently issued (and currently highest priority) SGI to fire and start doing its thing.  When it's done, it atomically sets A level equal to its own level.  Thus, while any of the SGI ISR's is processing, if another A interrupt occurs, the current SGI ISR's processing suspends; when the A interrupt is handled, the next-higher SGI ISR starts.  All higher level ISRs finish before a lower level ISR resumes.

"If that is what you want, fine". Yes, that is exactly what I want. And that is exactly what I'd like to know how to do.

@Alex, see edit 2

Your edit is more to the point of my question. Thanks. Unfortunately, if I understood your workaround correctly, if the code that runs on the interrupt takes long enough for that interrupt to be fired 40 more times, then 40 SGIs are needed, no? I'm writing a library, in fact, and I have no control over how long the code in the interrupt takes to run. It seems that "software simulating a return from ISR without actually returning" is the only option. Any ideas on how to accomplish that?

@Alex, feel free to upvote/select answer if useful.  ¶  Re how to accomplish software simulating return, I don't know how [on the SAM; its easy on AVR] or if its possible. ¶ Re "40 SGIs", apparently there are plenty of SGI numbers (0-239) available, and of course using task blocks for task data, only one SGI ISR needs to be instantiated, but of course there are only 16 priority levels on the SAM.  ¶ You haven't said what your overall aim is; it could be that re-entrant interrupts are not the best approach to it.  Maybe a threads or task-switching system would do the job.

I'd like to build from the ground up a very simple task based RTOS implemented around a periodic tick (the timer interrupt)

does not allow reentrant interrupts.

a few suggestions:
1) understand what "reentrant interrupts" means;
2) see if you need it;
3) see what needs to be done to get it to run on your hardware;
4) see if your code does what needs to be done.
hope it helps.

I'm sorry, but your answer doesn't answer anything. 1) I'm perfectly aware of what a reentrant interrupt is. 2) Yes, I need it. Or if I can achieve the same effect with something else, I would like to know if someone can point me in the right direction. 3) If I knew what needed to be done I wouldn't be asking this question. 4) No, it doesn't, or I wouldn't have a question.

Interrupt nesting: interrupt A can preempt handling of interrupt B; both interrupt A and interrupt B's handlers can be "active" at the same time.
Reentrant interrupt: interrupt A can preempt handling of interrupt A; interrupt A's handler can be active concurrently with itself.

authors: Артур Хисамов


text:
Good book/reference for AVR coding in pure C/C++?
Can someone recommend a good book/reference for going vanilla (i.e. not using arduino simplified language) on e.g. ATtiny85? I will need to use the equivalents of analogRead() and digitalRead() quite a bit. And is softwareserial the best method for debug output? I have less than 8KB of flash, so any advice on that (and reduction of binary for upload) would also be greatly appreciated.

Have you tried Atmel's datasheets and application notes?

Yes, I am looking for something to supplement those. A collection of commented programs for ATtiny85 would be good, or a beginner/medium book/reference. The avrfreaks forum is very good, but I need more.

First, let's make this clear: The Arduino environment does not provide a
“simplified language”: it provides a simple hardware abstraction layer
through its core library. The language is plain C++.
Like Talk2, I don't have good book recommendations. The basics of
low-level programming are covered in the Arduino tutorial on port
manipulation[]. Past this you will have to dig into the datasheet of
your MCU. Look also at the doc of the avr-libc and the tutorials in
Nick Gammon's microprocessors pages.
I would suggest you try to develop your program like this:

Do the initial prototype of your idea on an Arduino Uno (or similar)
using the Arduino libraries. It just makes things easier, and you are
more likely to get a working prototype pretty fast.
Once the initial idea works, optimize it for the limited resources of
the ATtiny85. This may involve replacing some call to the Arduino
libs with avr-libc and/or direct port access.
You may then want to remove all references to Arduino core, but you
don't have to: there are some ATtiny cores available that you can use
if you want.
If it now fits in less than 8 K, port to the ATtiny.

The thing I love about the Arduino environment is that you can very
easily mix and match abstraction levels: you can have, in the same
program, calls to Arduino core, to avr-libc, direct port access, and
even inline assembly if want to. You don't even need to stick to the
setup() and loop() method: you can write your own main() if you
prefer, just remember to call init() to initialize the Arduino core if
you are going to use it. Oh, and you don't have to use the Arduino IDE
either if you don't like it (I don't).
As for the optimization tips, I would recommend :

Use direct port access instead of digitalRead(), because that
function is pretty big and slow.
analogRead() may not be that bad, size wise, but it has a serious
shortcoming: it's a blocking function which spends 104 µs in a
spin loop, just waiting for the ADC result. If your CPU has better
things to do, you may want to implement a non-blocking read instead.
For debugging output, the most efficient option is likely to be the
USI port. You will have to search for a driver or implement your own
based on the Atmel application note AVR307: Half Duplex UART Using
the USI Module. Alternatively, you could use something like
AltSoftSerial. Do not use SoftwareSerial: it blocks interrupts for
insanely long amounts of time.
Use the command avr-nm --size-sort -Crtd my_program.elf to get a
listing of the functions of your program sorted by flash usage. This
will help you choose good targets for size optimization.

This is as near to perfect as reality permits. Thank you very much :)

I can recommend the book "Make: AVR Programming", which uses avr-gcc directly. The Arduino IDE is mentioned at one point, but just in order to "place" it, and to explain how to use its libraries in your own code. You can study all the code used in the book right here (github link).
(late answer, I know, I was searching for other books that don't use the Arduino IDE and stumbled upon this question)

If you abandon the Arduino paradigm you will be pushed into dealing with setting up all the hardware that makes today's embedded processor so flexible.  This usually takes an experienced embedded programmer days if not weeks to get through on a new processor.  You will also need a dedicated Atmel programmer as you will no longer be using the Arduino boot loader.
Once you get past these obstacles, you can start studying C and C++. The "grand dad" C reference book would be by the "first guys" that did C, Kernighan & Ritchie.  The equivalent C++ book (if you are up to it) would be by Bjarne Stroustrup.
However...
What have you gained by abandoning the Arduino paradigm?
Some would say, not much.
Most of why programming in the Arduino paradigm is easy has to do with Arduino libraries.  They "abstract" the hardware down to a couple simple function calls.  For example, with one function call you can set up the pulse train that can position a servo motor using a familiar term: degrees.
It should also be pointed out that the compiler Arduino uses is a C / C++ compiler.  And that most Arduino libraries are purposely written in C++.
Perhaps writing a C++ Arduino library is a good way to learn C++.  Start by finding the code to libraries that you already use.  Then reviewing how the C++ code is put together.  Finally write you own C++ Arduino library.

Sorry, I don't have any book recommendation apart from the AVR Datasheet.
You could try to use AVR-LIBC as a abstraction layer instead of playing directly with individual registers: http://www.nongnu.org/avr-libc/.
That might help you saving some Ks on your code which the Arduino layer might be adding. Just make sure you have a proper IDE to assist you with code-completion and navigation.
Also Atmel has a good link how to optimize your C code: http://www.atmel.com/images/doc8453.pdf, which I had a look when doing some bootloader coding.
Finally, you could explore the Arduino libraries, and see the overhead added to each function, like "analogRead()" from your example. Most of the Arduino funcions will be a layer on top of the AVR-GCC, so it'll be a good learning exercise - again, get a proper IDE that helps with auto-completion and navigation.
Cheers

avr-libc does very little to abstract the hardware: you are still going to access the hardware registers “manually”. Only it is easier with avr-libc, as it lets you write things like PORTB |= _BV(2); instead of * (volatile uint8_t *) 0x25 = 1 << 2;. The generated code is the same (namely sbi 0x5, 2).

The Arduino implements a subset of c++. I am not sure what you expect to achieve by not using it.
If you are really after optimum code, there is no obligation to use any inbuilt function and you can code your own.
Most conventional compilers use a standard runtime library. The reason Arduino does not is because of the limited memory. It is necessary to omit many standard functions to save space.
By not using a library only functionality you need is actually linked in.

The Arduino core is a runtime library, built on top of avr-libc, which is itself another runtime library. But the linker is smart enough to only link into your program the functions you do use.

@EdgarBonet if it only links used functions it is a library which produces a staticly-linked executable, but not a "runtime library" which is loaded in its entirety by the OS - non-existent on the Arduino.

Yes, these are statically linked libraries. If by “runtime library” you mean a library loaded in its entirety by the OS (I would call that a “dynamic library”), then no, there is not, simply because there is no OS. There is a “C runtime” though, courtesy of avr-libc (the files crt*.o): it contains the interrupt vector table, the catchall interrupt, the initializations of r1, SREG and the stack, and the calls to main() and exit().