text:
Sending struct from Arduino to Raspberry Pi - wrong types
I'm using Raspberry Pi and Arduinos for my home automation project where Raspberry Pi is the controler of Arduino nodes.
I use nRF24 wireless transceivers to communicate.
My problem is that when I was sending a structure like following
struct TempSensorData

{
      uint32_t result;
      uint32_t temperature;
      uint32_t humidity;
    };
From Raspberry to Raspberry everything went fine but now when I use Arduino as sender I get very strange results:
received: status: 335544320, temperature: 754974720 degrees, humidity: 0%

While on Raspberry it was
received: status: 0, temperature: 22 degrees, humidity: 44%

Can this be a problem with types? Or with different type of architecture (like different sizes on 3-2bit and 64-bit arch)?
EDIT:
Code on Raspberry:
if (radio.available())

{
        // dump the payloads until we've got everything
        Message receivedData = {0};
        radio.read(&receivedData, sizeof(Message));
        TempSensorData data = receivedData.msgData.tempSensorData;
        std::cout << "received: status: " << data.result << ", temperature: " << data.temperature << " degrees, humidity: " << data.humidity << "%" << std::endl; //TODO here we have some strange numbers - check if we have proper types
    }
Before that I have:
radio.begin();
radio.setPALevel(RF24_PA_LOW);
radio.setChannel(0x4c);
radio.openReadingPipe(1, RASPI_READ_ADDR);
radio.openWritingPipe(RASPI_WRITE_ADDR);

radio.enableDynamicPayloads();
radio.setAutoAck(true);
radio.powerUp();
radio.startListening();

And on Arduino:
Header header = {thisNodeId, thisNodeType, 0, static_cast<uint8_t>(MsgType::TEMP_SENSOR_DATA), 12345, Status::ok};
TempSensorData dhtData;
dhtData.result = DHT.read11(DHT11_PIN);
dhtData.humidity = (int)DHT.humidity;
dhtData.temperature = (int)DHT.temperature;
Message message = {0};
message.header = header;
message.msgData.tempSensorData = (dhtData);
radio.stopListening();
radio.write(&message, sizeof(message));
radio.startListening();

I also use a common header with defined structures for both Arduino and Raspberry, which contains:
#define RASPI_WRITE_ADDR 0xF0F0F0F0F0LL
#define RASPI_READ_ADDR 0xF0F0F0F0E1LL

struct TempSensorData {
  uint32_t result;
  uint32_t temperature;
  uint32_t humidity;
};

enum class Status : uint8_t

{
        ok,
        error,
        fail
    };
enum class MsgType : uint8_t {
    INITIALIZATION,
    RESET_REQUEST,
    ACK_NACK,
    TEMP_SENSOR_DATA,
};

struct Header {
  uint8_t nodeId;
  uint8_t nodeType;
  uint8_t location;
  uint8_t msgType;
  uint16_t checksum;
  Status status;
};

union MsgData {
  InitMsgData initMsgData;
  AckNack ackNack;
  TempSensorData tempSensorData;
};

struct Message {
    Header header;
    MsgData msgData;
};

radio is an item of RF24 class from https://github.com/TMRh20/RF24/
Unfortunately the RF24 repo is 64 commits ahead of what I use.
EDIT2:
Maybe the problem lays in that
enum class Status {};

which I use in both files.
I must add that I use g++-4.7 when compiling on Raspberry and when compiling on Arduino I use avr-g++-4.8.2

Can you post the arduino send code and and the raspi receive code?

I second that - posting the code will help the most.

I added code...

@yeti - "Tags should help to describe what the question is about, not just what it contains." The nrf chip is merely background context of the question, the actual issue is a difference of structure padding between the two C environments which has no dependence on the communication channel, so adding that tag (at least as a 3rd party edit proposal) is not appropriate.

It is not a size problem: uint32_t is always 32 bits. Converting the
numbers to hex gives:

Raspberry to Raspberry: 0x00000000, 0x00000016, 0x0000002c
Arduino to Raspberry: 0x14000000, 0x2d000000, 0x00000000

There seems to be an offset between the two. You may just have lost one
byte when the Arduino is the sender. There may be also a byte order
issue, but your test is not sufficient to say. You can, e.g., send a
series of 0x12345678 to know for sure.
You need to devise a way of synchronizing the communication, i.e. to
identify, in the byte stream, which is the first byte of the packet.
Edit: Let me illustrate how this can happen both with and without
and endianness issue. I'll assume you are transmitting
{status: 0, temperature: 20, humidity: 45} and the first byte(s) of
the first packet are lost. On the receiving side, you combine the
remaining bytes of the first packet with the first byte(s) of the second
packet, and interpret the whole as a single packet. You get:
{status: 335544320, temperature: 754974720, humidity: 0}.
In a little endian to little endian scenario, you only need to loose one
byte:
original data:     0x00000000, 0x00000014, 0x0000002d
transmitted bytes: 00 00 00 00 14 00 00 00 2d 00 00 00
received bytes:    00 00 00 14 00 00 00 2d 00 00 00 00
received data:     0x14000000, 0x2d000000, 0x00000000

In a big endian to little endian scenario, you get the exact same result
if you loose 4 bytes:
original data:     0x00000000, 0x00000014, 0x0000002d
transmitted bytes: 00 00 00 00 00 00 00 14 00 00 00 2d
received bytes:    00 00 00 14 00 00 00 2d 00 00 00 00
interpreted data:  0x14000000, 0x2d000000, 0x00000000

Off-by-a-byte synchronization issues can be a big challenge when working with streaming channels like UARTs, but the nRF24L01 is at least natively packetized, so I wouldn't expect that to be an issue here, unless the code driving it wraps the native behavior in a streaming abstraction that can split data across packets.   Another potential concern might be misaligned access on the pi side; would have to check if that throws a fault, aliases oddly to an aligned address, or gets fixed in software emulation.

I found out that adding "attribute((packed))" to all structs I'm sending helped! Thanks @EdgarBonet - your answer made me think and helped resolving this issue..

This answer is fundamentally wrong - in fact it is a size issue, specifically an alignment one where a multi-byte type follows a smaller type.  The pi wants the larger type aligned, the Arduino doesn't care.

I believe this could be because the Raspberry pi is big endian and the arduino is little endian.
Learn about Endianness here!

It's definitely not just an endianness problem since 0 appeared as a different number.

Without code detailing how the logistics is implemented, it could realistically be anything. It is important to factor in endianness however.

Are you sure about the Pi? I've read in several places it's little endian by default. AVR based Arduinos are little endian too. I do not know about the Due.

This is incorrect.  While the pi's hardware may be capable of running in a big endian mode, and there are people who have tried to do that http://raspberrypi.stackexchange.com/questions/7279/big-endian-distribution-for-the-raspberry-pi Most normal Raspberry Pi Linux distributions are little-endian

@ChrisStratton, thanks for the insight. I generally use Big Endian with the Pi out of habit - it sort of stemmed from ignorance in an operating systems Uni project years ago, and I have just sticked with it. I guess I jumped the gun and didn't even consider that the OP was probably using a *nix distribution. You're absolutely right!

You may have multiple problem.
First of all the structure get align to be efficient on the specific architecture, to avoid those filling you have to tell the compiler to pack the structure. There are different way to pack depending on compiler used.
Then endianess is different, so the byte composing the value has to be swapped.
Finally there may be a desincronization or a bus error. In those case a sync message (normally 2 byte before each transmission) and a CRC are used to fix the issue.

No, endianness is not different here.

I said "may". i listed the common mistakes, and the first one was actually the one that fixed the problem:<<I found out that adding "attribute((packed))" to all structs I'm sending helped!>>

The problem is that you made a false declarative statement in its own paragraph - if you did not mean to falsely argue that the endianness was different, you need to edit your post.  And even then, suggesting as a possibility something that is not true in the given case would be unhelpful and misleading.

yes, you are righr about phrasing, but english is not my maon language. If you propose an edit i can accept it.
About the answer, given the problem that is wat could be realistically the problems; this will be helpful to people having similar issue, but an other of the possible other cause


text:
How to prevent Arduino compiler from merging changing of port pin outputs into a single operation
I want to set one pin's output value, and then set a different pin's output value so that the two pins change value one after the other.
However, the compiler optimises the two calls to change both pins in one go.

PORTD |= _BV(0);    //set pd0 to high
PORTD |= _BV(1);    //set pd1 to high
PORTD &= ~(_BV(1)); //set pd1 to low

The two pins go high simultaneously. I tried inserting a NOP between these but it doesn't change behaviour.
(I originally intended to include an oscilloscope screengrab to show what was happening - that's how I knew (or got the wrong impression) that the two pins were changing at the same time. But the photo wasn't shifting from my Nexus 7 for me to access it from my laptop.)

I can't duplicate this behavior. Which version of GCC is in use?

What application requires those pins to be turned on one after the other, but so quickly that you don't need any code to cause a delay between the two?

Cool - there's an Arduino stackexchange! Thanks to the mods for migrating the question.

It sounds like I've just got myself confused here, since the behaviour I've seen isnt repro-able.

(by others, that is).

Granted I'm no expert on O-scopes, but given that the pin changes with separate calls will still happen in tens of nanoseconds, could a scope accurately detect the difference?

Well, when testing this as its own sketch I can see everything working properly - the delays between signal changes are quite evident.

I certainly can't duplicate what you are saying.  The small code snippet:
void setup() {
    PORTD |= _BV(0);
    PORTD |= _BV(1);
    PORTD &= ~(_BV(1));
}

void loop() {
}

compiles into:
000000a6 <setup>:
  a6:   58 9a           sbi 0x0b, 0 ; 11
  a8:   59 9a           sbi 0x0b, 1 ; 11
  aa:   59 98           cbi 0x0b, 1 ; 11
  ac:   08 95           ret

000000ae <loop>:
  ae:   08 95           ret

That is clearly two separate bit sets followed by a bit clear.
I am using UECIDE that is set to use GCC 4.3.2
If I switch to GCC 4.8.1 instead, the code generated is identical.
Even turning on full -O3 optimization I still get the same results.
So how are you determining that it's happening at the same time?

Which makes sense since the memory location has been declared as volatile.

I think I'm using Arduino IDE 1.06 but I will need to check when I get home.

I observed the two pins changing on an oscilloscope, but I will have to take a step back and do a test with the Arduino Micro removed from the project I'm working on. Sounds like I'm just mistaken.

Same code generated here with avr-gcc 5.4.0.

source: Stack Exchange

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

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

sort: votes


text:
Communication with Arduino and electronic device(for example tv or computer) through rs 232 cable

Say some electronic device (TV OR Computer) has an inbuilt program. Depending on received data from Ardiuno, it displays some text based on requirement. For example, if it receives 1 it should display 'error', else if it receives 0 it should display 'ready'.
I am working on only sending signals/bytes from Arduino Uno to some device which already has an inbuilt program. I just want to send 0 or 1 byte from the Ardiuno to the device using TTL to RS 232 COVERTER.
  this is the code

#include<SoftwareSerial.h>

 #define rxPin 0 //make pin o as rx pin

 #define txPin 1//make pin 1 as tx pin

 SoftwareSerial mySerial(rxPin ,txPin);//i donot undersatnd this line (i got
 the code from net//

 void setup()

 {

     pinMode(rxPin,INPUT);//making rx as input//
     pinMode(txPin,OUTPUT);//making tx as output//
     Serial.begin(9600);
     mySerial.begin(9600);
}

void loop() {
// put your main code here, to run repeatedly:
Serial.print(0x00);//i want to send 0 byte data from ardinuo to device //
delay(200);
}

I am using RealTerm software to check if the signals I have sent from the Arduino Uno are received as they have to be (without any interference).

I am sending continuously 0 from ardinuo to realterm in this case(for testing purpose). I am receiving in RealTerm in Hexadecimal format. Since I'm sending 0s continuously, I should be getting a continuous output of 0s on RealTerm as well. Instead, I am getting some random values initially (while uploading the sketch) and RealTerm stops displaying output soon after.
Can someone please help me solve my issue.
Update 1: i have modified my code as per @chrisl's  suggestion. Now, whn i send 0 i am getting a correct ouput ,but whn i am sending 1 contineosly i am  getting many 0's and random values

#include<SoftwareSerial.h>
#define rxPin 2
#define txPin 3
SoftwareSerial mySerial(rxPin ,txPin);
void setup()
 {
 pinMode(rxPin,INPUT);
  pinMode(txPin,OUTPUT);
  Serial.begin(9600);
  mySerial.begin(9600);
  }

  void loop() {
     // put your main code here, to run repeatedly:
  Serial.print(0x01);//i want to send 1 byte data from ardinuo to
  device(realterm)
  delay(200);
   }

RealTerm seems to display the hexadecimal values. Since you send the ASCII code for "0" (which is 30) (by using print() instead of write()) you should see a repeating 30 there. Don't assume zeros, when you are sending ASCII. Though this doesn't explain the seemingly random values you get.

You have configured pins 0 and 1 of the Uno for software serial, which makes no sense since those pins have hardware serial. Then you don't even use software serial in your code. You need to take the time to actually understand what the code does instead of just randomly copy pasting and hoping it might work. There is a ton of information available to you, use it!

use Serial.write(0), not Serial.print(0) if you want to send value 0 and not the character '0'

You have 2 problems:

You use the Serial.print() function, which outputs ASCII encoded characters. When sending "0" this way, actually the value 48 (or 30 in hex) will be send. RealTerm seems to display hexadecimal values, so you would get a long series of "30"'s. This is not really a big problem, you only shouldn't expect zeros to display there with this code. You can use the Serial.write() function to send direct byte values instead of ASCII codes.
You initiate the SoftwareSerial on the same pins, that are reserved for the Hardware Serial. This cannot work properly, because both libraries will try to use the same pins. Choose other pins for Rx and Tx of the SoftwareSerial interface.

EDIT:
Also you are setting pin modes for Rx and Tx of the SoftwareSerial. I don't know, if this can cause a problem, but at least you don't have to do this. The library will handle setting the pins correctly.
EDIT2: Further explanation about binary, hexadecimal and ASCII representation of the Serial byte stream
There are different methods to display a stream of byte data (like the stream from your Serial interface). Let's look at the decimal value (the one you are using when invoking arithmetic operations like +, -) 48. These are the different representation of this number in different numeral system (The first two characters mark the numeral system; 0b for binary, 0x for hexadecimal):

binary: 0b00110000
hexadecimal: 0x30

There are more numeral systems, but these are the most important ones. But the byte stream can also be used to look like a sequence of characters. For this the ASCII standard was born long time ago. In simple ASCII every value from 0 to 127 got assigned to a character or control action. The terminal program reads the byte stream and shows the corresponding characters according to the ASCII table. There are expansions to this model, to display more possible characters, but this is the very basic principle. With it, you are able to actually send human readable text from your Arduino to another device.
The Serial.print() function is made for this human readable text, so it will send an ASCII representation of the input parameter. The ASCII value of the character "0" is 48, which corresponds to a hexadecimal value of 30.
Now I'm not sure, if your terminal program shows hexadecimal or ASCII values. I though of the first, because all characters in your first image are digits or characters from A to F, which is the range of hexadecimal values. It didn't seem likely to not get other characters, when you have ASCII encoded text with random values in it. But I'm currently not sure, if the Serial.print() function would automatically print a hexadecimal representation in form of ASCII text, if given a hexadecimal value (I don't think so, but it might be possible). Please try to use the Serial.write() function and try sending different value while watching the output of RealTerm.
And please search for a settings, that determines, how the received byte stream is interpreted. This would make clear, what RealTerm is doing here. Also make sure you understand the relation between binary value and ASCII character. If this is still not clear enough, you can google for in detail explanations. There are tons of tutorials on that.

i have updated the question please check

as your suggestion i followed step 2 so ii am now able to get continuously output ,i can't understand 1 st part of your answer

@jalath I added further explanations.

According to basic serial communication principles, the transmitter (Tx) of the Arduino must be connected to the receiver (Rx) of the device. However, I am getting a correct output when I connect the transmitter of the Arduino to the transmitter pin of the device. Why is this so?

Perhaps the pin information on your device is wrong. You didn't specify, what you have there. Or the TTL RS232 converter might already twist the two lines. From the given information it is impossible to say

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


text:
Arduino configure script for conditional compilation of libraries
I have a library that uses conditional compilation based on the preprocessor variables. The library is a separate .cpp object file with a header file.
How can I pass preprocessor variables to the compilation of the library? Standard #define in a sketch file wouldn't work, since their life will be limited to my sketch object file(s), not the library's.
Normally it is solved by the ./configure script and/or the custom make process. How can I do it on Arduino?
Supplying a separate compilation/source code of the library for all 2^8 combinations of the preprocessor switches doesn't seem feasible...

The problem here is that the Arduino IDE is not setup for doing this. Any real IDE has the possibility to set defines.
If you want your library to be used by arduino IDE users you will have to go to dirty routes like the #include and config.h approach already mentioned.
If I'm not mistaken arduino IDE compiles libraries with the full include path so you can have the config.h next to your sketch.ino file.
If the library is not intended for arduino IDE users I would advice using a real IDE like my Arduino Eclipse Plugin.

I already use your excellent Eclipse Plugin. (I tested several other IDEs, but your proved to give me the best experience). But I'd prefer my library to compatible with the standard IDE if I had a choice. Setting the Eclipse with your plugin took me a half a day and two attempts... Not everyone will be able to do that.

V3 is comming. That should make it easy :-)

There's two basic methods:

Provide a config.h file with the options in that the user modifies
Place the options on the command line with -D

A decent IDE allows you to modify the compilation command line to add options.
My IDE, UECIDE, allows the creation of menu entries that set library options.

Ad 1. How to tell the library where is my config.h? When library's object file gets compiled, it doesn't know the location of my project's path. Or am I wrong?

The config.h is in the library. Depending on the IDE it may be possible to have it in the sketch folder and it'll find it there, but I am not sure what order of include paths the Arduino IDE uses.

Another solution: Rename the library's .cpp file into another .hpp, and let the user include it in exactly one object file of his.
User would configure the library in lib_customization.h included before every #include<lib.h>. User would also need to include an extra source file object_file_that_defines_lib.cpp which includes library definitions.
Sketch.ino:
#include"lib_customization.h"
#include<lib.h>

void loop() {}
void setup() {}

lib_customization.h:
#define LIB_INCLUDE_FEATURE_A
#define LIB_INCLUDE_FEATURE_B

object_file_that_defines_lib.cpp:
#include"lib_customization.h"
#include<lib_definitions.h>


text:
Smart way to map digital pins to a for loop over analogue pins
First post here and I have very little Arduino/c programming knowledge so forgive me my ignorance.
I am processing 18650 cells for a little powerwall project. I am using an Arduino pro mini atmega328p(5v) to read battery slot voltages and to turn on/off the tp4506 when the voltage reaches 3.85 volts for long term storage.
I am getting good voltage readings and after some trouble having a common ground with the tp4506 I think I have isolated it with a couple diodes.
I am using a 30N06L n channel mosfet to switch the tp4506's on and off, shutting them off to get the reading then back on till next voltage reading. I am learning a lot and having fun with it.
My problem stems from me not really having firm grasp of terminology or Arduino C. I cannot find my solution from search engine results after a few hours searching on and off.
I am using a for loop over 3(for now) analogue pins to get my voltage readings. What I can't figure out is how to map those pins to the digital pins controlling the mosfets from the loop. I have a few different versions of this project just trying to get a feel for what is the most efficient way to do it(I like the loop). How do I map or correlate AO with D2 and so forth. It's very frustrating not being able to type what I want out in a way that get's me some code I can learn from so I hope another human can understand my issue.
const int aRefVoltage = 5.00;
float voltage         = 0;

void setup() {
  // put your setup code here, to run once:
  pinMode(2, OUTPUT);
  Serial.begin(9600);
}

void loop() {
// put your main code here, to run repeatedly:
// read the input on analog pin 0-2

  for (int i = 0; i < 3; i++) {
    int sensorValue = analogRead(i);
    delay(700);

// float voltage = sensorValue * (aRefVoltage / 1024.0);
    voltage = sensorValue*aRefVoltage/1024.0;
// print out the value you read:
    Serial.print( F("  Slot-") );
    Serial.print(i + 1); // +1 to match slot number
    Serial.print( F(" = ") );
    Serial.print(voltage);
    Serial.print( F(" Volts") );

    if (i == 2) Serial.println("     ");
    Serial.println( F("") );
  }

}

What is the smartest way to map analogue "i[0]" to the digital pin 2 to turn on that slots mosfet while using the for loop? Switch case? I hope I was clear enough in my question.
Thank you
edit: inb4 I get chewed out.
I am not looking for the answer to be handed to me. I would like a link to a tutorial that will show me how to use i[1] either in or out of the loop so I can use it....or how to use it.  An explanation from my would be hero would be nice too.
My searches all got me very rudimentary for loop examples and endless tutorials on how to turn analogue pins into digital pins. Surprising amount of tutorials on how to do that out there.

edit 2
A ce pin? That sounds handy I will have to look into that. I am sure my use of diodes would make an engineer shake his head. I have limited supplies on hand and this is really my first project where I have a use for my tinkering.
On each analogue pin I have two 10k resistors. One to pull down and the other to prevent the batteries from sending juice back through the analogue pin.
I spent several hours trying to use the 1.1 volt internal reference but even after calculating what my 1.1 actually was my results were not as accurate and it just seemed like slapping a dmm across the rail and dialing the knob on the buck converter was practical.
https://provideyourown.com/2012/secret-arduino-voltmeter-measure-battery-voltage/
and
    internal1.1Ref = 1.1 * Vcc1 (per voltmeter) / Vcc2 (per readVcc() function)
For diodes I have a 1N4001 between the battery negative on tp4506 chip and  ground. If I did not have it there power was flowing back through the chip. I was also playing with a 3v zener on the positive side to block .5 volts to my analogue reading when no battery present in slot.
I have no doubt I am doing it incorrectly I wasn't expecting those issues and was just trying to hack a solution together, luckily my aim is not charging to 4.2 or I would be up a creek.
Thank you again for taking the time to show me the code I needed. I should be able to figure it out from here. As long as I am moving forward I am content. I had been at it for ten hours by the time I broke down and made this post. I was pretty burnt out and knew if I could just see an example I would be good to go.

edit 3
const int aRefVoltage        = 5.00;
const int readVoltagePins[3] = { A0, A1, A2 };
const int chargePin[3]       = { 2, 3, 4 };
const int hysteresis         = 0.10;
float voltage                = 0;

void setup() {
  // put your setup code here, to run once:
  for (int i = 0; i < 3; i++) {
    pinMode(chargePin[i], OUTPUT);
  }
  Serial.begin(9600);
}

void loop() {
  // put your main code here, to run repeatedly:
  // read the input on analog pin 0-2

  for (int i = 0; i < 3; i++) {
    digitalWrite(chargePin[i], LOW);
    delay(1500);
    int sensorValue = analogRead(readVoltagePins[i]);
    float voltage = (float) sensorValue * (5.0 / 1024.0);

    // Write here code to turn on the digital pin on (once) if the voltage
    // is too low and off (once) with hysteresis.
    // The digital pin is: chargePin[i]

    if (voltage <= 1.50) {
      digitalWrite(chargePin[i], LOW);
      Serial.print( F("  Slot-") );
      Serial.print(i + 1); // +1 to match slot number
      Serial.println( F(" = NFG || Empty ") );
      break;
    }

    else if (voltage <= (3.85 - hysteresis)) {
      digitalWrite(chargePin[i], HIGH);
      Serial.print( F("  Slot-") );
      Serial.print(i + 1); // +1 to match slot number
      Serial.print( F(" = ") );
      Serial.print(voltage);
      Serial.println( F(" Volts & Charging") );
    }

    else if (voltage >= (3.85 + hysteresis)) {
      digitalWrite(chargePin[i], LOW);
      Serial.print( F("  Slot-") );
      Serial.print(i + 1); // +1 to match slot number
      Serial.print( F(" = ") );
      Serial.print(voltage);
      Serial.println( F(" Volts & !Charging") );
    }

  }
  delay(5000); // increase later
  for (int i = 0; i < 3; i++) {
      if (i == 2)
      Serial.println("     ");
  }
}

This is what I have for code for now. I am just leaving the b- disconnected on the cloned charging boards. Let me know what you think @Jot

Is the programming code for A0 to D2 the same as for the other pins ? Then you could put the pin numbers in an array and run them in a for loop.
The TP4056 has a CE pin, why don't you use that to turn then on and off ?
The accuracy of reading a voltage with an Arduino depends on the accuracy of the voltage reference. You use the VCC 5V as reference. Is your 5V a stable and accurate 5.00V ? Did you measure the 5V pin of the Arduino board ?
Did you protect the analog inputs with a resistor ?
What did you do with the diodes ? Can you show a schematic (it can be a photo of a drawing) ?
An array with analog pins and digital pins:
const int readVoltagePins[3] = { A0, A1, A2 };
const int chargePins[3] = { 2, 3, 4 };

In the setup, set the digital pins as outputs:
for (int i=0; i<3; i++)
{
  pinMode (chargePins[i], OUTPUT);
}

In the loop, use a similar for-loop. I declare the locally used variables locally.
for (int i=0; i<3; i++)
{
  int sensorValue = analogRead(readVoltagePins[i]);
  float voltage = (float) sensorValue * (5.0 / 1024.0);

  // Write here code to turn on the digital pin on (once) if the voltage
  // is too low and off (once) with hysteresis.
  // The digital pin is: chargePins[i]
}

Reaction to edit 3
The idea of StackExchange is to have a question with an answer. Both the question and the answer can be polished along the way to create something that is helpful for others.
Developing a Arduino sketch is something else. I don't know either what the best way is to reply.
What about taking the average value of about 30 (5 to 1000) samples ? If the voltages are not steady, then averaging will help a lot.
The internal voltage reference of 1.1V is not bad, but the actual voltage can be between 1.0 and 1.2V. It is different for each Arduino board. You can measure the AREF pin with a multimeter after setting the 1.1V reference and put the measured voltage in the sketch in the calculation.
If the power to the Arduino board is a good 5.0V and the Arduino is always at the same room temperature, then the internal voltage of 1.1V can be used to measure a battery with 20mV accuracy, and perhaps 5mV with a lot averaging.
You use a delay to slow down the sketch. It is okay to do a digitalWrite over and over again during charging or during idle. In the comment I wrote to do that once, because I was anticipating to use millis instead of delays.
Because of the delay, the if_else_if_else_if is nice and straightforward code.
An integer can not be 5.0 or 0.10. Please check your whole sketch for 'float' versus 'int'. If floating point is needed, then use floating point. The voltage is a 'float', therefor it is best to use 'float' everywhere the voltage is used, for example the hysteresis.
I still don't understand the diodes. Can you make a schematic ?
Using a mosfet is probably okay, but I have to see the schematic.

I am not sure the correct way to reply to you so I edited my question.

While looking into the ce pin I realize that I have clones of the tp4056. I have a tc4056 and a 4056e. Talk about rabbit holes. The data sheet on the tc doesn't show a ce pin for 8 but a chrg. Is there anything wrong with using the mosfet to supply/cut power to these clones? http://jimlaurwilliams.org/wordpress/?p=4731

@ether Added a section: Reaction to edit 3

I can't thank you enough for your input. I have 3 slots working well, I will fix the float/int issue, easy enough. I also have to work out the hysteresis a bit better, maybe save the last read and compare. I installed fritzing this morning but then got sidetracked. I will try and get to it but the weekend is almost over so don't hold your breath. The diodes aren't being used. Solved by just leaving the bat - unattached. Not sure how cool that is but it is working just fine as is.

Also as for the voltage readings. They are consistently .01 volt off of my meter. Since the initial function is to get to 3.85 for storage I am not too concerned about the accuracy just yet. I have noticed that all the batteries I have brought up to 3.85 sag back down after a few loops also. I am assuming it is saturation of sorts. Until the next phase I would be content with less accuracy.

Fritzing does not make normal schematics. The free version of Eagle was used a long time. Today some prefer KiCad for hobby use. I read at hackaday.com that they prefer KiCad because it is open source. You can draw something on a piece of paper with a pen and make a photo of it.

OK, bare with me, the work week does not afford me much time.

Here is a drawing, I hope it is legible. freeimage.host/image/kLfXZ and here is a pic of my cigar box lid. freeimage.host/image/kL8fq thinking maybe shouldn't be having those battery leads running under the buck boost converter. and here is the rats nest. freeimage.host/image/kLMiI

The 10k to protect A0 is good. The 10k to keep the gate low is also good. Sometimes a protection resistor of 100 ohm is used for the gate: http://www.pighixxx.com/test/portfolio-items/connect-a-mosfet/ The charging module is not ment to be used like that. Keeping the charging module connected to the 5V input and switch the GND input and keep the BAT+ connected to the batteries... it depends on the charger module what will happen. Can you measure the current from the charger to the batteries when the mosfet is turned off ?

I will, I am also wondering if they will stop themselves at 4.2 while wired without the b- or if they would just keep going. I will run some tests this weekend.  Thanks for the interest.

What I can't figure out is how to map those pins to the digital pins controlling the mosfets from the loop.

you probably will have to do a better job articulating what "mapping" an analog pin to digital pins means.
If the issue is "associating" an analog pin with a digital pin, a struct would do, like this:
typedef struct {
  uint8_t apin; //analog pin
  uint8_t dpin; //digital pin associated with the analog pin
} PIN_TYPE;

PIN_TYPE pins1, pins2; //two sets of pins

 ...
 if (analogRead(pins1.apin) < BAT_THRESLOW) turn_on(pins1.dpin); //if voltage is too low, start charging it
 if (analogRead(pins2.apin) > BAT_THRESHIGH) turn_off(pins2.dpin); //if voltage is too high, stop charging.

Obviously, the logic should be more comprehensive to avoid oscillation.

Dear @dannyf, due to a mistake my "Reaction to edit 3" got somehow into your answer. Please ignore or remove it.

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


text:
Dynamic Serial port selection and use without instantiating all Serialx objects
I have an arduino project that reads a config file from SD and then receives data on a serial port that is specifed in the config file.
I therefore need to instantiate the Serial (Serial0), Serial1,..2,3, etc based on dynamic data.
I am using a mega2560 with 4x HardwareSerial. Serial (also Serial0) is the USB. Serial 1, 2, 3 are on specific hardware pins.
I started with code something like:
uint8_t InitPort(uint8_t port) {
    switch (port) {
        case 0:
            if(Serial.begin(9600) return 1;
            break;
        case 1:
            if(Serial1.begin(9600) return 1;
            break;

        ... etc...

        default:
            return 0;
}

However, this instantiates all Serialx objects (using 157 bytes of data/bss each).
I've since written a class wrapper that takes a referece to the desired serial object as an initialising paramter, but this just pushes the problem up-stack to the calling code.
Is there a way that a Serial object can be instanitated dynamically with a port number passed in, to only end up with one instance connected to the desired port?

Do you speak about SoftwareSerial interfaces or the hardware interfaces?

they are all instanced, but optimized away if the code doesn't use it. the class of Serials depends on the board. on some boards Serial is USB and Setial1 is HardwareSerial. but on boards with 328p it is something like HardwareSerial Serial(&UBRRH, &UBRRL, &UCSRA, &UCSRB, &UCSRC, &UDR);

Post editied to clarify mega2560 - hardware serial.

@Juraj they are not optimised away by the linker in my appliction (which is the problem) becuase the linker does not know which one will be use at runtime - this is based on user config data read from the SD. So it includes all 4 with assoicated memory use which is the underlying problem.

all are used in your sketch in some case, so must be in the final build.

@TisteAndii, it is not so complicated. only the instances must be created dynamically as Edgar shows in the answer

but what is 3 times 157 bytes in 8 kB SRAM of the Mega? :-)

sometimes it really matters :-) https://forum.arduino.cc/index.php?topic=622002.msg4215655#msg4215655

You can create an instance of HardwareSerial referencing a hardware
port that depends on a function parameter, as in
void initPort(uint8_t port) {
    switch (port) {
        case 0: {
            HardwareSerial serial(&UBRR0H, &UBRR0L,
                     &UCSR0A, &UCSR0B, &UCSR0C, &UDR0);
            serial.begin(9600);
            break;
        }
        case 1:
            // etc...
    }
}

However, since only a local variable can be created in this manner, it
is not of much use. Ideally, you would want to have a global variable
for the serial port, and initialize it in initPort(), as
HardwareSerial serial;

void initPort(uint8_t port) {
    switch (port) {
        case 0:
            // Invoke fictional init() method.
            serial.init(&UBRR0H, &UBRR0L,
                     &UCSR0A, &UCSR0B, &UCSR0C, &UDR0);
            break;
        case 1:
            // etc...
    }
    serial.begin(9600);
}

Alas, this is not possible, as the HardwareSerial class has no default
constructor. This means that binding the object to the hardware port can
only be done when it is constructed.
Short of modifying the Arduino core (adding a default constructor and an
init() method), the only option I can see is to have the global
variable be a pointer. Then, in initPort() the object is
instantiated while initializing the pointer. I tried this approach in
the example program below. There was a slight technical difficulty
though: since the object files from the core defining Serial,
Serail1, etc. will hopefully not be linked to the program, the
interrupt service routines defined therein must be also defined in the
sketch itself. And since an ISR cannot be bound to an interrupt at run
time, the ISRs have to be defined for all the ports, even though only
one ends up being actually used.
Here is my test program:
#include <HardwareSerial_private.h>

HardwareSerial *serial;

ISR(USART0_RX_vect) { serial->_rx_complete_irq(); }
ISR(USART1_RX_vect, ISR_ALIASOF(USART0_RX_vect));
ISR(USART2_RX_vect, ISR_ALIASOF(USART0_RX_vect));
ISR(USART3_RX_vect, ISR_ALIASOF(USART0_RX_vect));
ISR(USART0_UDRE_vect) { serial->_tx_udr_empty_irq(); }
ISR(USART1_UDRE_vect, ISR_ALIASOF(USART0_UDRE_vect));
ISR(USART2_UDRE_vect, ISR_ALIASOF(USART0_UDRE_vect));
ISR(USART3_UDRE_vect, ISR_ALIASOF(USART0_UDRE_vect));

void initPort(uint8_t port)
{
    switch (port) {
        case 0:
            serial = new HardwareSerial(&UBRR0H, &UBRR0L,
                         &UCSR0A, &UCSR0B, &UCSR0C, &UDR0);
            break;
        case 1:
            serial = new HardwareSerial(&UBRR1H, &UBRR1L,
                         &UCSR1A, &UCSR1B, &UCSR1C, &UDR1);
            break;
        case 2:
            serial = new HardwareSerial(&UBRR2H, &UBRR2L,
                         &UCSR2A, &UCSR2B, &UCSR2C, &UDR2);
            break;
        case 3:
            serial = new HardwareSerial(&UBRR3H, &UBRR3L,
                         &UCSR3A, &UCSR3B, &UCSR3C, &UDR3);
            break;
    }
    serial->begin(9600);
}

void setup() {
    initPort(0);
    serial->println("Hello, World!");
}

void loop(){}

It should be noted that the ISRs do not take that mush flash space.
There are actually only two of them, even though each is referenced four
times in the interrupt vector table.

Excellent that you have shared your progression to the answer. Many thanks. Now for the next learning deep dive - understanding ISRs properly on arduino and getting accross all the U variables in the HardwareSerial class. I presume they are registers of some sort?

@BrendanMcL: If you want to dig deeper, you will have to read the chapter “USART” of the ATmega2560 datasheet, and the chapter “Interrupts” of the avr-libc documentation.

@BrendanMcL: The “U variables” are references to hardware I/O registers. For example, UBRR0H is a macro that expands to (*(uint8_t*)0xc5), where 0xc5 is the memory-mapped address of the “USART0 Baud Rate Register High Byte”.

@Edgar_Bonet many thanks. Understood. Having so many great libraries on the arduino platform is a great upside for working quickly. Downside being that it abstracts away so much detail making it a full learning curve to do something outside the spec.


text:
Trying to read from AD5934 using Arduino on I2C
I'm trying to read a block of bytes from an AD5934 Impedance converter (PDF) using I2C.
This is my code so far
Preamble:
#define AD5934_Address                    0xD
#define AD5934_Start_Frequency            0x82
#define AD5934_Block_Read                 0b10100001
#define AD5934_Address_Pointer            0b10110000

Loop:
void loop() {
  readAD5934(AD5934_Start_Frequency, test, 3);
}

Read Function:
byte readAD5934 (int address, long int  data, int len) {
  byte err = 0, counter;

  if (len > 32)
    return 0xFF;

  else if (len > 1) {
    // Part ONE
    Wire.beginTransmission(AD5934_Address);
    Wire.write((byte) AD5934_Address_Pointer);
    Wire.write((byte) address);

    err = Wire.endTransmission();

    // Part TWO
    Wire.beginTransmission(AD5934_Address);
    Wire.write((byte) AD5934_Block_Read);
    Wire.write(len);

    // Part THREE
    Wire.requestFrom(AD5934_Address, len);
    StartHigh = Wire.read();
    StartMed = Wire.read();
    StartLow = Wire.read();
    err = Wire.endTransmission();
  }
return err;
}

For some reason, the Arduino tries to read the three bytes before Part TWO is executed.
I'm aware that I'm ending the I2C transmission after the requestFrom. The datasheet for AD5934 describes how to read a block of bytes on page 26. It does not show a STOP CONDITION before the end.
The oscilloscope shows
START 0001101 WRITE ACK 10110000 ACK 10000010 ACK STOP START 0001101 READ ACK 00000001 ACK 11000111 ACK 11111111 NACK STOP START 0001101 WRITE ACK 10100001 ACK 00000011 ACK STOP
Short:
S 0x0D W A 0xB0 A 0x82 A P S 0x0D R A 0x01 0xC7 0xFF NA P S 0x0D W A 0xA1 A 0x03 A P
The highlighted part (requestFrom and three Wire.read()) should be at the end.
I've spent a long time trying to figure this out, any help would be very much appreciated.
PS. Working on a Sparkfun Pro Micro 5V

Is there a Wire.endTransmission(false) missing before Part THREE?

A Wire.requestFrom does the stop itself. You may not do a Wire.endTransmission after it. Part TWO needs the Wire.endTransmission as @MikaelPatel wrote. What might happen is this: the Wire.requestFrom reads data, and the Wire.endTransmission after or inside the Wire.requestFrom might execute what already is written in a buffer in Part TWO. It depends on the code of the Wire library and it should not be done like that.

I think you should re-see AD5934x datasheet.
To read data from AD5934, we have three ways:

read single byte
read block
using pointer command

If you want to read multi byte, you can refer to my way:
unsigned long GetRegisterValue(unsigned char regAddr, unsigned char len)
{
    unsigned long regValue = 0;
    unsigned char index;
    unsigned char wrData[2] = {0,0};
    unsigned char rdData[2] = {0,0};

    for (index = 0; index < len; index++)
    {
        wrData[0] = 0xB0; //assign pointer cmd
        wrData[1] = regAddr + index;
        I2C_Write(AD5934_ADDR, wrData, 2);
        rdData[0] = 0xff;
        I2C_Read(AD5934_ADDR, rdData, 1);
        regValue <<= 8;
        regValue += rdData[0];
    }

    return regValue;
}


text:
Which WiFi module is able to host a custom web UI and can act as a station and AP?
I am an Arduino beginner. I am searching for a WiFi module that can act as a station and access point. It should have a external antenna.
I need to upload a script that starts a web server, so I can host my custom UI where the user can enter his WLAN credentials. After the credentials are set, it should try to connect to that WLAN like in the example script below, from a YouTube video.
I've tried the ESP8266, but uploading my script also overwrote the firmware.
Someone suggested the "Wemos D1 mini", but it does not have a big antenna and the one that I found with an antenna on Amazon has really really bad reviews.
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <EEPROM.h>
ESP8266WebServer server(80);

struct settings {
  char ssid[30];
  char password[30];
} user_wifi = {};

void setup() {
  EEPROM.begin(sizeof(struct settings) );
  EEPROM.get(0, user_wifi);
  WiFi.mode(WIFI_STA);
  WiFi.begin(user_wifi.ssid, user_wifi.password);
  byte tries = 0;
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    if (tries++ > 30) {
      WiFi.mode(WIFI_AP);
      WiFi.softAP("Setup Portal", "mrdiy.ca");
      break;
    }
  }
  server.on("/", handlePortal);
  server.begin();
}

void loop() {
  server.handleClient();
}

void handlePortal() {
  if (server.method() == HTTP_POST) {
    strncpy(user_wifi.ssid, server.arg("ssid").c_str(), sizeof(user_wifi.ssid));
    strncpy(user_wifi.password, server.arg("password").c_str(), sizeof(user_wifi.password));
    user_wifi.ssid[server.arg("ssid").length()] = user_wifi.password[server.arg("password").length()] = '\0';
    EEPROM.put(0, user_wifi);
    EEPROM.commit();
    server.send(200, "text/html", "<!doctype html><meta charset='utf-8'><meta name='viewport' content='width=device-width, initial-scale=1'><title>Wifi Setup</title>
Wifi Setup

Your settings have been saved successfully!
Please restart the device.
" );
  } else {
    server.send(200, "text/html", "<!doctype html><meta charset='utf-8'><meta name='viewport' content='width=device-width, initial-scale=1'><title>Wifi Setup</title>    <form action='/' method='post'>
Wifi Setup

SSID<input type='text' class='form-control' name='ssid'>

Password<input type='password' class='form-control' name='password'>

<button type='submit'>Save</button>
mrdiy.ca
</form> " );
  }
}

why is overwritten firmware a problem? why do you want a big antenna?

If I override the firmware, then my device does not respond to AT commands and the wifi does not work at all.
To be able to transmit and receive data over a bigger distance, at least 20 meters.

the wifi not working isn't related to the firmware. but that is a separate question.

Thx, I will ask another question then.

About the bad reviews: A lot of them complain about the necessity to desolder a 0Ohm SMD resistor for using the external antenna. Maybe you can find a similar kit with higher quality and without that desoldering job at a more reputable seller. As you seem to be located in germany, maybe reichelt or conrad, or internationally mouser. Haven't searched them for such a kit, but the quality on amazon is often the same as buying clones directly from china over aliexpress or similar.

@chrisl, yes and not only that, they also replaced a diode with a 0 Ohm resistor which can destroy the USB slot of your PC. I also made the experience that amazon more and more becomes like wish. The sellers also buy 5 star reviews by trying to bribe users with money / gift cards. I will search on another shop, thx

20 meters doesn't require any external antenna.

@Delta_G well, obviously It depends how many obstacles are in the way and how far the router is away. In my case the device will be put a few meters underground inside of a well, so I need a external antenna which I can place more at the top.

What do you mean depends on how far the router is away.  You said it was 20 meters.  You didn't mention anything about any well.

"uploading my script also overwrote the firmware" well, yeah... You're replacing the firmware, so obviously you can't have AT commands anymore.

@Delta_G so you automatically assumed that there are no obstacles in the way at all, only because I mentioned the distance is 20 meters? Thats a weird conclusion.

@dda is there a way to upload a sketch without also replacing the firmware?

I think the thing that you are not understanding is that the sketch and firmware are the same thing.  You only get one program on there.  The firmware is like a sketch that is preloaded and responds to AT commands.  You can write a program that also responds to AT commands or does any other thing you want.  But you cannot replace the program on the chip and then expect to still be able to use it.

@Black - I assumed nothing.  You didn't say there were any obstacles.  It's foolish to ask for help with something and then hide information about it.

I will try to answer some of the misunderstandings, though this is not really a full answer, since I currently don't know what the exact problem is.
First some terms:

Firmware: A firmware is a program running on a device. What we refer to as firmware is commonly the result of the compiled code, so a program in machine language. (Though sometimes people talk about firmware and mean the firmware code, which is not compiled at that time). In the world of microcontrollers, a firmware runs directly on a microcontroller's hardware (as opposed to a PC, where there is an OS in between). Thus only 1 firmware can run on the microcontroller at any given time. You cannot upload multiple firmwares to a microcontroller at the same time. Thus uploading a new one will overwrite the previous one.
Sketch: This is the Arduino term for your programs code. When you compile your sketch, the compiler will translate your code into assembler and then into machine language. The resulting file can then be uploaded to the microcontroller, where it overwrites the previous content of the flash memory.
SDK: A Software Development Kit is a set of code that provides easy to use access to important functionalities. The Arduino framework itself can be called a SDK. It provides easy to use access for commonly used microcontroller functionality, like digital and analog inputs. If you program an ESP through the Arduino IDE, it will have a copy of the ESP SDK, which gives easier access to complex things like Wifi handling. This ESP SDK comes from the company that makes the ESPs: Espressif. If someone wants to write a program for an ESP, like a firmware that speaks AT commands over serial that someone will get the ESP SDK from Espressif.
AT firmware: The AT firmware is not really different to your own program that you write/compile in the Arduino IDE. It uses the ESP SDK to handle things like Wifi. And it listens on the ESPs serial port for AT commands and reacts to them. You can write your own AT firmware, if you want to. This type of firmware is to provide simpler microcontrollers without Wifi hardware a network connection through Wifi. The simple microcontroller can send AT commands over serial to control the Wifi connection. Though this is of course inefficient and limited. It can be good to incorporate Wifi into an existing project, though when you try to do more complex stuff it is often better to ditch the simpler microcontroller and do everything directly on the ESP with your own custom firmware. No need for AT commands then.

why the WiFi and AT commands are not working anymore after uploading a sketch

As described above, you have created and uploaded your own firmware, by writing a sketch for the ESP in the Arduino IDE and uploading it. That program overwrites the one that was previously saved on the ESP. Thus the AT firmware is gone now. If you want to restore it, I'm sure you can find a fitting one for your board online and upload that again.
Though from what you have written so far it seems to me that you don't really need an AT firmware. Programming a custom portal for Wifi credentials is something where you need your own firmware anyway. You are now sitting at the place of the AT firmware with your own program. You can tell it what to do by writing the corresponding code.

Which WiFi module is able to host a custom web UI and can act as a station and AP?

Every ESP board is capable of that as far as I know. Though I haven't seen an AT firmware yet that would support setting up a custom web UI. So you would need to write your own firmware.

Someone suggested the "Wemos D1 mini", but it does not have a big antenna and the one that I found with an antenna on Amazon has really really bad reviews.

Most ESP boards are not made with an external antenna as a priority. Even the ones with a socket for an external antenna might require some work to set them from internal to external antenna (like desoldering a resistor). You might be able to find one that doesn't require this. The Wemos D1 mini pro unfortunately requires the desoldering of the 0Ohm resistor. That is set by the manufacturer, so any reseller would do the work themselves. Not many will do that.
I cannot help you with finding such a board, as I don't know one (didn't need an external antenna yet). I would also just Google it.
And for better quality you need to go to reputable sources. Amazon is often just as a bad gamble as directly buying from China, AliExpress or similar. If you buy there, expect the quality to be rather low and some boards might even be broken. Sometimes that is OK, sometimes not.
Note: I'm really not an expert in RF, but honestly I would be surprised if connecting the antenna via a multiple meter-long cable wouldn't impact signal strength significantly. The ESP Wifi hardware is probably not built for driving the charge into such a long antenna. If this is the case it might be better to rethink your project design. You could put the ESP on top of the well (easily in reach of the Wifi network) and connect whatever you have down in the well from there. Or you could use another microcontroller handling the things in the well, connecting to the ESP via cable. Or if you absolutely need Wifi to connect down there, you might use an extender at the top of the well (can also be done by an ESP, if you don't want a full Wifi extender there). This very much depends on your exact requirements, so only a few ideas here.

Also I've noticed that in your handlePortal() function you are copying the SSID and password into the user_Wifi struct, but you are not actually changing the Wifi status. I would expect the code to do a change from AP to Station mode or reconnecting to the new Wifi.
You are saving the credentials into EEPROM (which is just flash on an ESP) and retrieving it on the next startup. I've made that error many times myself: when the expected Wifi network from the ESP doesn't show up, are you sure that there are no valid Wifi credentials saved from your previous run?

I hope that this helps you a bit.

"The ESP wifi hardware is probably not build for driving the charge into such a long antenna".  This is what I found with the ESP-07.  The losses in the cable far outweighed the gain from the antenna.  In the end it worked much better with the built in ceramic antenna, even when the antenna lead was kept to just a few cm.

So the SDK is permanent on the ESP and can't get overridden by flashing the flash memory?

No, the SDK is a software component on your PC, that is referenced by your own sketch (whenever you use Wifi in there for example). When you compile your own sketch,  the compiler also compiles the relevant parts of the SDK and puts both into one single binary, which then can be uploaded to the ESP. The SDK is needed when compiling a program for the ESP to access its special functions (like Wifi), so that the compiler knows how the calls to them should look like.

Thank you for the helpful informations @chrisl, I appreciate it


text:
Using 1.1Vf to read stable battery voltage and sensor voltage
After several tries, i was successful with reading stable battery voltage using internal voltage reference of 1.1v, now the issue i face is that i cannot read stable sensor voltage, could you please let me know how can i read my sensor voltage? or do i need additional voltage divider (my sensor goes directly to A0 and GND pin).
  void setup(){
  Serial.begin(9600);
}

void loop() {
  //REFS1 AND REFS0 to 1 1 -> internal 1.1V refference
  ADMUX |= B11000000;
  //We read A1 (MUX0) for battery voltage
  ADMUX |= B00000001;
    //We read A0 for sensor voltage
  ADMUX |= B00000000;                // for my sensor
  // Start AD conversion
  ADCSRA |= B11000000;
  // Detect end-of-conversion
  while (bit_is_set(ADCSRA,ADSC));
  float val = ADCL | (ADCH << 8);
  val = val * 5.7; // Using 4.7k and 1k voltage divider
  Serial.println(val);
}

Something like the code below must workout but unfortunately it does not help!
  int sensorValue = analogRead(A0);
  voltage =  ((sensorValue/ val) * 1023.);
  delay(1000);
  Serial.println("voltage:  ");
  Serial.print(voltage);
  if (voltage<=215){
  digitalWrite (led, HIGH);
  }
  else if (voltage>=215){
  digitalWrite (led, LOW);
  }

I cannot find the issue, it should work, i believe.
//////////////////////new edit/////////////////////////////////////
const long internalReference = 1078L; //measured AREF to be 1.078 ~ 1.078*1000= 1078V

void setup() {
  // put your setup code here, to run once:
Serial.begin (115200);
}

void loop() {
 analogReference (INTERNAL);
 ADMUX |= B00000000;
 ADCSRA |= B11000000;    //ADEN and ADSC equal to 1   (Start conversion)
  while(bit_is_set(ADCSRA, ADSC));    //Wait for conversion to end
  long val = ADCL | (ADCH << 8);   //Get analog read value
  float voltage = (val/internalReference)*1024;
 Serial.println (voltage);

 }

Looking at your past posts, you are repeatedly using the wrong code and then asking why it doesn't work. Maybe you should search how the ADC work. The reading from sensorValue = analogRead(A0) is a value ranging from 0 to 1023, to convert it to a voltage, the formula is voltage = (sensorValue/Vref) * 1023, where Vref is the reference Voltage you are using, in this case, it is 1.1v. Furthermore, you can't get a correct sensorValue if your input at A0 is HIGHER than the Vref, you will get the wrong value!

@hcheung ok,understood. i will change now and update. before i do so please ans my question:    1) if i use vref as 1.1v, do i need to measure my battery voltage, will it affect the code in any way? because my system only requires sensor measurement that's it.  i am following this link (http://electronoobs.com/eng_arduino_tut156.php) that says we need to measure battery voltage then we can use it with the sensor code. i will update you with the results please stay connected

Whether you want to measure and calibrate the Vref, it is +/-10% differences according to datasheet (I mentioned this already on my prefer answer, please read them). so that means the Vref could be in the range of 0.99 - 1.21v.

@hcheung Hi, please check the code above it displayed constant 0.00V. i have connected solar to a voltage divider that drops the voltage down to 0.85V.

In the schematic above the LDR has been used in place solar panel due to the unavailability of the component in the software.

internalReference should be '1.1` or the voltage you actually measured with a volt meter at Vref. What is the resistance of the LDR?

Let us continue this discussion in chat.

To measure the voltage at A0 with an internal reference of 1.1v, the formula is float voltage = 1.1 * analogRed(A0) / 1023;. Your code can be simplified as
float Vref = 1.1;

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

void loop() {
  analogReference (INTERNAL);
  float voltage = Vref * analogRead(A0) / 1023;
  Serial.print (“voltage at A0:”);
  Serial.println(voltage);
  Serial.print (“Solar panel voltage:”);
  Serial.println(voltage * 5.7);
  delay(1000);
}


text:
Reading constant battery voltage and using the obtained value in sensor formula
there i am working on a project in which my system is connected to 3.7v~4.2V lithium battery, I have to read constant battery voltage irrespective of the current battery voltage and to do that I am using internal voltage reference (1.1V). My issue is that before adding sensor code my program was reading constant voltage irrespective of any battery level but the moment I add sensor code to it, the battery voltage readings fluctuate.

You still have some problems as all the other times you have asked this question. You need to make the minimal version of the code that works as you expect, and then show what change you make that produces output you do not expect. (1) do not mix Arduino analog pin functions with direct register access. Pick one or the other (you should pick arduino). (2) remember that you can only real voltages between 0-1.1V with the 1.1V. Any voltage higher than 1.1V will read as max value (1.1V) against this reference.(3) you are using A1 in your code, but A1 is not connected to anything in your schematic.

People want to help you, but you have to help them to help you! By continuing to ask the same question over and over and over again you wasting the time of the nice people trying to help you and you are not even getting solutions to your problem. Make the simplest version of the program that works. This is probably measuring the battery voltage though the bridge using A0 pin using only Arduino function. This should be a very short program. Make sure it really works as you expect across all potential voltages you might see.

I know you just want someone to give you a quick fix, but you have already spent way way more time asking this question over and over again than you would have to systematically work your way through this problem! Start simple, understand what is going on. I promise! :)

@bigjosh It is working, i needed stable output. As you said i have removed all register function and using simple arduino code. please check above

My issue is that i want to connect my solar panel to positive and negative of battery but the moment i make the connection my sensor reads 1023 which it obviously should. so, is there a way to separate out or connect.

i believe my measuring scale of 1.1 is way too small it reaches 1023 when the multimeter reads around 1V

"My issue is that i want to connect my solar panel to positive and negative of battery" this is a different question than the one asked here.

"i believe my measuring scale of 1.1 is way too small it reaches 1023 when the multimeter reads around 1V" Yes, when measuring a voltage using the 1.1V reference, you would expect voltages near 0V to read the value 0 and voltages near 1.1V to read a value near 1023 (remember the +/-10%).

You should re-check my answer on how to measure Vcc against the 1.1V from one of the first times you asked this question. This is what you actually want to do.

@bigjosh ok i understood now that it is not required to measure battery voltage in order to read sensor value. I used internal reference voltage and measured my panel and i was successful in reading exact proper values with the resolution of 0-1023.

@bigjosh Now the problem i face is, when i use the same code with attiny it does not work.

ok i think it will work now the issue was with the code, instead of >= i made <= that's why the code was not working

If you set the Vref with the internal reference of 1.1v, then the voltage presented at analog pin A1 is simply as:
const float Vref = 1.1; // according to datasheet there is a +/-10% variance, need calibration to confirm the actual value

analogReference(INTERNAL);
float VA1 = Vref / 1023.0 * analogRead(A1); // voltage at analog pin A1
float Vbat = VA1 * 5.7;                     // battery voltage

For more accurate measurement. you can use a multimeter to measure the actual Vref, and use the actual measurement in your sketch as the Vref value. BTW, if you are using battery, you may want to change your voltage divider to 47k and 10k to reduce the current draw by the voltage divider.

sure, i will use the exact vref value. Is it 47k or 4.7k? because i have used 4.7k and if i change my 1k to 10k, do i need to change the value (5.7) in the program?, we need one pin just to read the battery voltage right?

Use 47k and 10k resistors, the ration will still be the same (47000+10000)/10000. But this only draw current of 3.7/(47000+10000) = 65uA, versus when using 4.7k+1k which draw 0.65mA. 10 times difference.

Your original post mentioned nothing about any light sensor, it was asking how to read the battery voltage. If my answer help you answered that question, please accept the answer by click on the 'tick' and upvote it so that future reader know this is a correct answer. Feel free to post another question regarding your lighting sensor question with your code separately.


text:
Having an issue conveying array values properly
this is my first time asking a question here, sorry in advance if this is a poor way to ask this question.
I'm at an intermediary point in coding a program, and at this stage I'd like my byte information which I'm inputting into my serial monitor to take the places of my array elements. I'm able to do so, but when I try to use a 5 digit input, I only get a 4 digit input in return.
It seems like my Serial.available() == 4 loop is preventing my Serial.available() == 5 loop from operating. Would there be a simple modification I could make to allow a 5 digit result from a 5 digit input, and a 4 digit result from a 4 digit input? I've tried many things and Chat GPT seems to think the current code should work, but it doesn't. Here's the code:
int fiveArray[5];
int fourArray[4];
const char* colors[] = {"black ", "brown ", "red ", "blue ", "yellow ", "orange ", "white ", "gold ", "green ", "purple "};

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

  Serial.print("Input a number value: ");
  Serial.println();
}

void loop() {
  if (Serial.available() ==5 ) {
    char tempArrayFive[6];
    Serial.readBytes(tempArrayFive, 6);
    tempArrayFive[5] = '\0';

    for (int i = 0; i < 5; i++) {
      fiveArray[i] = tempArrayFive[i] - '0';
    }

    Serial.print("Color Value: ");
    for (int i = 0; i < 5; i++) {
      Serial.print(colors[fiveArray[i]]);
    }
    Serial.println();

  }
  if (Serial.available() == 4 ) {
    char tempArrayfour[5];
    Serial.readBytes(tempArrayfour, 5);
    tempArrayfour[4] = '\0';

    for (int i = 0; i < 4; i++) {
      fourArray[i] = tempArrayfour[i] - '0';
    }

    Serial.print("Color Value: ");
    for (int i = 0; i < 4; i++) {
      Serial.print(colors[fourArray[i]]);
    }
    Serial.println();
  }
}

"It seems like " - great observation, sending one byte (10bits with start and stop bits) using 9600baud per second takes around 1ms. On the other side Arduino on 16MHz during that time can handle 16000 instruction cycles - my guess is over 200 loops() between 4th and 5th character...

Can you please include a sample of what you are sending from the Serial Monitor and what line ending you have set there? Your current code doesn't make much sense to me. As KIIV wrote you have a race condition between the two if statements, but you also read 6 (and 5) bytes but you overwrite the last one with zero for string termination. You talk about byte data, but from your code it seems, that you are using ASCII encoded text (important difference when handling the data)

OT concerning ChatGPT: Never trust a chat bot, it has no idea about programming, it is just good at putting words together. Do not mix perfect grammar and wording with knowledge!

"this is my first time asking a question here": Since you are supposedly a intelligent person, you want to take the [tour] and read "[ask]" as well as other pages of the [help].

Yes, if you send 5 bytes to the Arduino then they will arrive one at a time.  When the 4th byte arrives then the if (Serial.available() == 4 ) statement is true and it runs that code.  That code reads from the buffer which means that the part that checks for 5 bytes will never be able to run.  There will always be 4 before there is 5.
A better idea would be to send your bytes with a start and end marker.  The program on the Arduino will read bytes and collect them in an array until it sees the end marker.  Then you can count how many bytes you have received if you want to take different actions depending on that number.
Here's a nice thread on handling Serial data:  https://forum.arduino.cc/t/serial-input-basics-updated/382007

I have a post here which discusses handling incoming serial data. Also here on Stack Exchange.
For handling serial input like you are trying to do I suggest using an "end of line marker" like newline (which the Terminal Monitor in the IDE will do for you automatically).
Then it's just a case of seeing whatever-it-was you got before the newline. Example code:
/*
Example of processing incoming serial data without blocking.

Author:   Nick Gammon
Date:     13 November 2011.
Modified: 31 August 2013.

Released for public use.
*/

// how much serial data we expect before a newline
const unsigned int MAX_INPUT = 50;

void setup ()
  {
  Serial.begin (115200);
  } // end of setup

// here to process incoming serial data after a terminator received
void process_data (const char * data)
  {
  // for now just display it
  // (but you could compare it to some value, convert to an integer, etc.)
  Serial.println (data);
  }  // end of process_data

void processIncomingByte (const byte inByte)
  {
  static char input_line [MAX_INPUT];
  static unsigned int input_pos = 0;

  switch (inByte)
    {

    case '\n':   // end of text
      input_line [input_pos] = 0;  // terminating null byte

      // terminator reached! process input_line here ...
      process_data (input_line);

      // reset buffer for next time
      input_pos = 0;
      break;

    case '\r':   // discard carriage return
      break;

    default:
      // keep adding if not full ... allow for terminating null byte
      if (input_pos < (MAX_INPUT - 1))
        input_line [input_pos++] = inByte;
      break;

    }  // end of switch

  } // end of processIncomingByte

void loop()
  {
  // if serial data available, process it
  while (Serial.available () > 0)
    processIncomingByte (Serial.read ());

  // do other stuff here like testing digital input (button presses) ...

  }  // end of loop

In your case, you would put code in the process_data function to turn the input text into a number and then do something with that number.
I'm surprised ChatGPT didn't point out my code <grin> but maybe you asked it a too-specific question.

I'd just point out that without a line-terminator character (like newline) then your code will be permanently out of step with incoming data if it starts in the wrong place. For example:
123456789

Depending on the speed at which that arrives, are we seeing 123 followed by 456? Or 12 followed by 34? Or 1234 followed by 5678? The end-of-line delimiter is really essential to avoid those ambiguities.
Or if the code happens to start running after you have sent the 1 but before the 2 it would think you sent 234 rather than 123 and then every other number would be out by one position.


text:
Testing Logic Gates using Arduino
hello guys is there someone who can help me with my first project.
its basically about logic circuits.
by using tact switch and pull-up resistor to set the values to logical 1 or 0.
the output can be verified by using a LED as an indicator.
so the code goes like this:
//AND GATE
int pin2=1;         //set pin2=1
int pin3=1;         //set pin3=1

void setup()
{
pinMode(2,INPUT);
pinMode(3,INPUT);
pinMode(4,OUTPUT);
pinMode(11,OUTPUT);
pinMode(12,OUTPUT);
}
void loop()
{
  pin2=digitalRead(2);
  pin3=digitalRead(3);

 if(pin2==1)            //turn led on pin11 when pin2 =1
 {
 digitalWrite(11,HIGH);
 }
 else
 {
 digitalWrite(11,LOW);
 }

 if(pin3==1)          ////turn led on pin12 when pin3 =1
 {
   digitalWrite(12,HIGH);
 }
 else
 {
   digitalWrite(12,LOW);
 }

//TRUTH TABLE OF AND

  if(pin2 && pin3)
  {
    digitalWrite(4,HIGH);
  }
  else
  {
  digitalWrite(4,LOW);
  }
}

//OR GATE
int pin2=1;
int pin3=1;

void setup()
{
pinMode(2,INPUT);
pinMode(3,INPUT);
pinMode(4,OUTPUT);
pinMode(11,OUTPUT);
pinMode(12,OUTPUT);
}
void loop()
{
  pin2=digitalRead(2);
  pin3=digitalRead(3);

 if(pin2==1)
 {
 digitalWrite(11,HIGH);
 }
 else
 {
 digitalWrite(11,LOW);
 }

 if(pin3==1)
 {
   digitalWrite(12,HIGH);
 }
 else
 {
   digitalWrite(12,LOW);
 }

//TRUTH TABLE OF OR

  if(pin2 || pin3)
  {
    digitalWrite(4,HIGH);
  }
  else
  {
  digitalWrite(4,LOW);
  }
}

//NAND GATE
int pin2=1;
int pin3=1;

void setup()
{
pinMode(2,INPUT);
pinMode(3,INPUT);
pinMode(4,OUTPUT);
pinMode(11,OUTPUT);
pinMode(12,OUTPUT);
}
void loop()
{
  pin2=digitalRead(2);
  pin3=digitalRead(3);

 if(pin2==1)
 {
 digitalWrite(11,HIGH);
 }
 else
 {
 digitalWrite(11,LOW);
 }

 if(pin3==1)
 {
   digitalWrite(12,HIGH);
 }
 else
 {
   digitalWrite(12,LOW);
 }

//TRUTH TABLE OF NAND

  if(!(pin2 && pin3))
  {
    digitalWrite(4,HIGH);
  }
  else
  {
  digitalWrite(4,LOW);
  }
}

can you guys help me to run this in one sketch by using tact switch  to select the logic gate to be tested or run? thank you in advance

This cannot work: pin2, pin3, setup() and loop() are all defined three times. You cannot paste three programs one after the other and expect the whole to be a valid program. Just run one program at a time. If you have no push button, use a wire that you manually connect and disconnect to/from GND (if using a pullup resistor) or 5V (if using a pulldown).

@EdgarBonet actually combining both programs in one seems to be the actual question here :-)

For simulating different gates with the same program, an option is to
use the serial port to tell it what gate you want it to simulate. Here I
am also using a function pointer (called gate) to represent the
selected gate:
/* Wiring. */
const int inputA    = 2;
const int inputB    = 3;
const int outputA   = 11;
const int outputB   = 12;
const int outputRes = 4;

void setup()
{
    pinMode(inputA,    INPUT_PULLUP);
    pinMode(inputB,    INPUT_PULLUP);
    pinMode(outputA,   OUTPUT);
    pinMode(outputB,   OUTPUT);
    pinMode(outputRes, OUTPUT);
    Serial.begin(9600);
    Serial.println(F("Type 'a'(for AND), 'o' (OR) or 'n' (NAND)."));
}

/* Available gates. */
bool AND(bool a, bool b)  { return a && b; }
bool OR(bool a, bool b)   { return a || b; }
bool NAND(bool a, bool b) { return !(a && b); }

/* The gate we want to test. */
bool (*gate)(bool a, bool b) = AND;

void loop()
{
    // Select the gate through the serial port.
    switch (Serial.read()) {
        case 'a': gate = AND;  Serial.println("AND");  break;
        case 'o': gate = OR;   Serial.println("OR");   break;
        case 'n': gate = NAND; Serial.println("NAND"); break;
    }

    // Simulate the gate.
    bool a = !digitalRead(inputA);  // input is in negative logic
    bool b = !digitalRead(inputB);
    digitalWrite(outputA, a);
    digitalWrite(outputB, b);
    digitalWrite(outputRes, gate(a, b));
}

Here is another version, that uses an enum instead of a function
pointer to identify the gate. The constants and the setup() are the
same as before, then:
void loop()
{
    // The gate we want to test.
    static enum { AND, OR, NAND } gate;

    // Select the gate through the serial port.
    switch (Serial.read()) {
        case 'a': gate = AND;  Serial.println("AND");  break;
        case 'o': gate = OR;   Serial.println("OR");   break;
        case 'n': gate = NAND; Serial.println("NAND"); break;
    }

    // Simulate the gate.
    bool a = !digitalRead(inputA);  // input is in negative logic
    bool b = !digitalRead(inputB);
    digitalWrite(outputA, a);
    digitalWrite(outputB, b);
    bool res = false;
    switch (gate) {
        case AND:  res = a && b;    break;
        case OR:   res = a || b;    break;
        case NAND: res = !(a && b); break;
    }
    digitalWrite(outputRes, res);
}

What about something like this:
const uint8_t    inA =  2;
const uint8_t    inB =  3;
const uint8_t   outA =  4;
const uint8_t   outB = 11;
const uint8_t   outY = 12;
const uint8_t button =  5;

void setup() {
    pinMode(inA, INPUT_PULLUP);
    pinMode(inB, INPUT_PULLUP);
    pinMode(outA, OUTPUT);
    pinMode(outB, OUTPUT);
    pinMode(outY, OUTPUT);

    pinMode(button, INPUT_PULLUP);
}

uint32_t check_time = 0;

uint8_t     counter = 0;
uint8_t       funct = 0b0110; // start with XOR

void loop() {
    // active low: (for usage with buttons connected to ground with internal pullup)
    // uint8_t state = (digitalRead(inA)==LOW) | (digitalRead(inB)==LOW)<<1;

    // active high:
    uint8_t state = (digitalRead(inA)==HIGH) | (digitalRead(inB)==HIGH)<<1;

    digitalWrite(outA, (state & 1) > 0);
    digitalWrite(outB, (state & 2) > 0);

    digitalWrite(outY, ((funct >> state) & 1) > 0);

    // button handling
    uint32_t actual = millis();
    if (actual > check_time) {
        check_time = actual + 4; // check every 4ms

        if (digitalRead(button) == LOW) { // expects pull-up and active low
            if (++counter == 4) { // debounce - confirmed after 16ms (4*4) and every 256*4 ms again
                funct = (funct + 1) & 0xF;
            }
        } else {
            counter = 0; // reset counter
        }
    }
}

It uses push button to cycle through all 16 possible functions of two inputs.
Default is XOR. Assumption is Active HIGH inputs (you can use INPUT instead of INPUT_PULLUP).


text:
Using ESP8266 core for Arduino
I am working on a wireless sensor network project, in which data is collected at a central node using nRF24 modules and the RFNetwork.h library.
I want to post that to the internet using the famous ESP8266 module, which works fine when used as standalone and programmed with Arduino IDE. But the problem is how to transfer my data from Arduino to the ESP8266 as it only has one serial that is already used to program it?
I have tried to use a nRF24 module that uses SPI with an ESP-12 as it has an SPI header, but it didn't work out and I can't figure out the problem. Is there a way to use ESP core libraries like esp8266wifi.h, wifiClient.h, webserver.h etc., just like we can use the esp8266.h library that uses AT commands to communicate to ESP from an Arduino like in a master-slave manner?

Maybe another solution is to link your ESP to one of your Arduino (or a new one, with an NRF24). If you have an ESP-1 you can use serial transmission with AT commands. For ESP-12, it must be possible too, through SPI as you mentioned.

Several solutions:

Are your SPI components 5V or 3.3V parts? The ESP8266 is 3.3V only, and is NOT 5V-tolerant; you may have already fried it.
In most cases that I've had problems with SPI with the ESP8266 (in particular, the Adafruit 8266-12E HUZZAH board), they went away when I drastically lowered the SPI speed to 8000000.
Once you've programmed the 8266, and assuming you don't use Serial for debugging output, it's free to use to communicate with the world. Again, be careful about signal levels -- the 8266 is NOT 5V-tolerant, and most arduinos have 5V signals. So either use a 3.3V arduino-like part (my favorite is the Teensy 3.2 for larger projects, and the Adafruit Trinket for smaller ones), or use a level converter. If you need debugging output, you can still use Serial1 for output only (and don't forget to change its bit rate -- by default it's something crazy like 74380bps).
Run the 8266 as another SPI slave and have the Arduino write to it. Or come up with your own serial protocol! Again, careful about signal levels.
You can use a different version of the 8266 (or another wifi chip), one that's already meant to be used with the Arduino. Sparkfun and Adafruit have several, as do a lot of other vendors.

I'd still suggest that you try to work out the SPI problems and stick to the 8266.
Also, don't forget that neither serial nor SPI guarantees data integrity. Always use a CRC to make sure your data were transferred correctly, and have some provision for retransmissions if you can't afford to just ignore corrupted data.
/ji

actually, according to several articles I've read, the ESP8266 is 5V tolerant on GPIO - of course, that's input, if the connected component requires 5v input signals, then you're out of luck

Seems like you have several options:

1. Find a nRF24 library that works on ESP with the "arduino core" or port one yourself.
2. Implement your own Arduino-to-ESP protocol, using Serial (SoftwareSerial if needed), I2C or whatever.
3. Flash the ESP with the standard AT commands firmware and command it from the Arduino.

IMO, option 1 is best (you would ditch the Arduino completely), but may require significant effort.
Option 2 is academically better than option 3, as it will skip the hassle of dealing with AT commands on the Arduino side and will eventually be more efficient in terms of data bandwith between the Arduino and the ESP. In practice, it probably won't matter.
Option 3 might be the easiest - as much as I dislike the AT commands, they work and you won't have to program two devices constantly while developing your code.

So, in short, if you can go with Option 1 - please do so :)
If not - quickly asses which one will be easier / better for you - option 2 or option 3 and just go with it. Both will work, and are relatively easy to achieve.

...but the problem is how to transfer my data from Arduino to the
  ESP8266 as it only has one serial that is already used to program it.

After you flash a new firmware serial port becomes free so you can use it for whatever you like.
ESP8266 has two serial ports, not only one (although you can use only TX pin from the second one as RX is connected to SPI bus of the flash).
You can use any free GPIOs for software serial communication.

You can find the details about ESP8266's serial porth here, here, here and here.

(It sounds like you have already used the esp8266 so I hope this background isn't too simple, but I'm not sure from your question where you're stuck.)
The ESP8266 modules are programmable. They are (usually) delivered with an application program installed that uses the manufacturer-defined set of "AT<something>" commands to operate it as a WiFi station or access point. There are code libraries for Arduinos or other computers to set it up and use it that way.
You can use its one serial port for either job - communicating to its current application program (interpreter, or your own custom program), much as you do an Arduino's port.
You can program your entire application on the chip and operate its WiFi radios directly, just as the AT-command interpreter does. You'll need the specs for programming the radios though; the AT-interpreter does that for you. Once you've loaded an application program of your own, it replaces the interpreter. To put it back to as-delivered, with the AT-command interpreter running in it, you'll need to re-upload the interpreter (which of course will replace anything else you've loaded).

authors: พงศธร พักวัง


text:
Arduino two Ethernet shields
Is it possible to connect two Ethernet shields to arduino? And if yes, how can I distinguish them in the code?

You need to move the SS pin for one of the shields (Arduino pin 10). That way you can select which shield you want to talk to.

I don't think you can do this because the Ethernet.begin statement isn't an instance of Ethernet so I don't think you can do this.

Technically it is possible. Maybe you will have to  write your own library. But... Why? Why do you need two ethernet shields? I'm pretty sure the main problem is another one... Please tell us what you really want to achieve, so smarter solutions can be suggested (see The XY Problem). I'm telling you this because even if you have two shields you won't be able to do much work with them...

The ENC28J60 Shields have a Chip-Select-Pin (CS) so you could select between the two shields with this.

I'm using the EN28j60 with the Ethercard library and I'm not sure if this could handle two Ethernet shields because you have to set the CS pin at init on the first call in the function, and can't change it at runtime.

As I know you can High or Low any pin at runtime.

As far as I know, the library doesn't have any provision to use multiple shields/modules because I tried to do it and it kept disconnecting.
Let me know if you had any success doing that.


text:
Does an Arduino 101 come with bluetooth HID capabilities?
I would like to prototype an Ergodox-like keyboard. My take on this good design would be to affix each half of the keyboard to my chair's armrests, so that the arms are always in a natural relaxed position. In order to achieve this, bluetooth capabilities seem necessary in order to avoid cable mayhem each time I move the chair.
I am aware that the Arduino Leonardo has USB-HID capabilities, but will that translate to the additional USB module that would be required? I saw that Adafruit has an EZ-key bluetooth module that seems to fit the bill, but even so, it would require more cabling and complexity, for a project that is already very near my threshold (or above it).
What would be easy is if the Arduino 101 had HID capabilities. I would just need to solder the matrix of keys, and almost be done. Does it?
Thanks for your attention.

The Arduino 101 has HID capabilities. I found example code for using the Arduino 101 as a keyboard, as well as some other discussions saying that the Arduino 101 has HID capabilities.
Here is some example code on GitHub.


text:
ADXL345 gives wiring error in SPI mode
I get the following output from serial monitor when trying to use the ADXL345 with Arduino Uno in SPI mode (I2C mode works fine):
CA
Ooops, no ADXL345 detected ... Check your wiring!

See photos for wiring. I have tried it with another breakout board, and that produces the same results.
Interestingly this tutorial says the breakout should work in SPI mode, but it's only illustrated for I2C.
https://learn.adafruit.com/adxl345-digital-accelerometer?view=all#assembly-and-wiring
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_ADXL345_U.h>
/* Assign a unique ID to this sensor at the same time */
Adafruit_ADXL345_Unified accel = Adafruit_ADXL345_Unified(13,12,11,9);
//Adafruit_ADXL345_Unified accel = Adafruit_ADXL345_Unified();

//Adafruit_ADXL345_Unified accel = Adafruit_ADXL345_Unified(clock,miso,mosi,cs,sensorID);
void displaySensorDetails(void)
{
  sensor_t sensor;
  accel.getSensor(&sensor);
  Serial.println("------------------------------------");
  Serial.print  ("Sensor:       "); Serial.println(sensor.name);
  Serial.print  ("Driver Ver:   "); Serial.println(sensor.version);
  Serial.print  ("Unique ID:    "); Serial.println(sensor.sensor_id);
  Serial.print  ("Max Value:    "); Serial.print(sensor.max_value); Serial.println(" m/s^2");
  Serial.print  ("Min Value:    "); Serial.print(sensor.min_value); Serial.println(" m/s^2");
  Serial.print  ("Resolution:   "); Serial.print(sensor.resolution); Serial.println(" m/s^2");
  Serial.println("------------------------------------");
  Serial.println("");
  delay(500);
}

void displayDataRate(void)
{
  Serial.print  ("Data Rate:    ");

  switch(accel.getDataRate())
  {
    case ADXL345_DATARATE_3200_HZ:
      Serial.print  ("3200 ");
      break;
    case ADXL345_DATARATE_1600_HZ:
      Serial.print  ("1600 ");
      break;
    case ADXL345_DATARATE_800_HZ:
      Serial.print  ("800 ");
      break;
    case ADXL345_DATARATE_400_HZ:
      Serial.print  ("400 ");
      break;
    case ADXL345_DATARATE_200_HZ:
      Serial.print  ("200 ");
      break;
    case ADXL345_DATARATE_100_HZ:
      Serial.print  ("100 ");
      break;
    case ADXL345_DATARATE_50_HZ:
      Serial.print  ("50 ");
      break;
    case ADXL345_DATARATE_25_HZ:
      Serial.print  ("25 ");
      break;
    case ADXL345_DATARATE_12_5_HZ:
      Serial.print  ("12.5 ");
      break;
    case ADXL345_DATARATE_6_25HZ:
      Serial.print  ("6.25 ");
      break;
    case ADXL345_DATARATE_3_13_HZ:
      Serial.print  ("3.13 ");
      break;
    case ADXL345_DATARATE_1_56_HZ:
      Serial.print  ("1.56 ");
      break;
    case ADXL345_DATARATE_0_78_HZ:
      Serial.print  ("0.78 ");
      break;
    case ADXL345_DATARATE_0_39_HZ:
      Serial.print  ("0.39 ");
      break;
    case ADXL345_DATARATE_0_20_HZ:
      Serial.print  ("0.20 ");
      break;
    case ADXL345_DATARATE_0_10_HZ:
      Serial.print  ("0.10 ");
      break;
    default:
      Serial.print  ("???? ");
      break;
  }
  Serial.println(" Hz");
}

void displayRange(void)
{
  Serial.print  ("Range:         +/- ");

  switch(accel.getRange())
  {
    case ADXL345_RANGE_16_G:
      Serial.print  ("16 ");
      break;
    case ADXL345_RANGE_8_G:
      Serial.print  ("8 ");
      break;
    case ADXL345_RANGE_4_G:
      Serial.print  ("4 ");
      break;
    case ADXL345_RANGE_2_G:
      Serial.print  ("2 ");
      break;
    default:
      Serial.print  ("?? ");
      break;
  }
  Serial.println(" g");
}

void setup(void)
{
#ifndef ESP8266
  while (!Serial); // for Leonardo/Micro/Zero
#endif
  Serial.begin(9600);
  Serial.println("Accelerometer Test"); Serial.println("");
  pinMode(9,OUTPUT);
  /* Initialise the sensor */
  if(!accel.begin())
  {
    /* There was a problem detecting the ADXL345 ... check your connections */
    Serial.println("Ooops, no ADXL345 detected ... Check your wiring!");
    while(1);
  }

  /* Set the range to whatever is appropriate for your project */
  accel.setRange(ADXL345_RANGE_16_G);
  // displaySetRange(ADXL345_RANGE_8_G);
  // displaySetRange(ADXL345_RANGE_4_G);
  // displaySetRange(ADXL345_RANGE_2_G);

  /* Display some basic information on this sensor */
  displaySensorDetails();

  /* Display additional settings (outside the scope of sensor_t) */
  displayDataRate();
  displayRange();
  Serial.println("");
}

void loop(void)
{
  /* Get a new sensor event */
  sensors_event_t event;
  accel.getEvent(&event);

  /* Display the results (acceleration is measured in m/s^2) */
  Serial.print("X: "); Serial.print(event.acceleration.x); Serial.print("  ");
  Serial.print("Y: "); Serial.print(event.acceleration.y); Serial.print("  ");
  Serial.print("Z: "); Serial.print(event.acceleration.z); Serial.print("  ");Serial.println("m/s^2 ");
//  delay(500);
}

I got it to work using the Sparkfun library in stead of the Adafruit library, and by inserting a couple of delay(100) statements in the setup (without them the output was continuously -13365, -13365, -13365). I still don't fully understand why the delay statements would be necessary in the first place though.
/*  *********************************************
 *  SparkFun_ADXL345_Example
 *  Triple Axis Accelerometer Breakout - ADXL345
 *  Hook Up Guide Example
 *
 *  Utilizing Sparkfun's ADXL345 Library
 *  Bildr ADXL345 source file modified to support
 *  both I2C and SPI Communication
 *
 *  E.Robert @ SparkFun Electronics
 *  Created: Jul 13, 2016
 *  Updated: Sep 06, 2016
 *
 *  Development Environment Specifics:
 *  Arduino 1.6.11
 *
 *  Hardware Specifications:
 *  SparkFun ADXL345
 *  Arduino Uno
 *  *********************************************/

#include <SparkFun_ADXL345.h>         // SparkFun ADXL345 Library

/*********** COMMUNICATION SELECTION ***********/
/*    Comment Out The One You Are Not Using    */
ADXL345 adxl = ADXL345(9);           // USE FOR SPI COMMUNICATION, ADXL345(CS_PIN);
//ADXL345 adxl = ADXL345();             // USE FOR I2C COMMUNICATION

/****************** INTERRUPT ******************/
/*      Uncomment If Attaching Interrupt       */
//int interruptPin = 2;                 // Setup pin 2 to be the interrupt pin (for most Arduino Boards)

/******************** SETUP ********************/
/*          Configure ADXL345 Settings         */
void setup(){

  Serial.begin(9600);                 // Start the serial terminal
  Serial.println("SparkFun ADXL345 Accelerometer Hook Up Guide Example");
  Serial.println();

  adxl.powerOn();                     // Power on the ADXL345
  delay(100);
  adxl.setRangeSetting(16);           // Give the range settings
                                      // Accepted values are 2g, 4g, 8g or 16g
                                      // Higher Values = Wider Measurement Range
                                      // Lower Values = Greater Sensitivity
  delay(100);
  adxl.setSpiBit(0);                  // Configure the device to be in 4 wire SPI mode when set to '0' or 3 wire SPI mode when set to 1
                                      // Default: Set to 1
                                      // SPI pins on the ATMega328: 11, 12 and 13 as reference in SPI Library
  delay(100);
//  Set SPI mode to that matching ADXL345 (I guess this would be in here by default? )

  adxl.setActivityXYZ(1, 0, 0);       // Set to activate movement detection in the axes "adxl.setActivityXYZ(X, Y, Z);" (1 == ON, 0 == OFF)
  adxl.setActivityThreshold(75);      // 62.5mg per increment   // Set activity   // Inactivity thresholds (0-255)

  adxl.setInactivityXYZ(1, 0, 0);     // Set to detect inactivity in all the axes "adxl.setInactivityXYZ(X, Y, Z);" (1 == ON, 0 == OFF)
  adxl.setInactivityThreshold(75);    // 62.5mg per increment   // Set inactivity // Inactivity thresholds (0-255)
  adxl.setTimeInactivity(10);         // How many seconds of no activity is inactive?

  adxl.setTapDetectionOnXYZ(0, 0, 1); // Detect taps in the directions turned ON "adxl.setTapDetectionOnX(X, Y, Z);" (1 == ON, 0 == OFF)

  // Set values for what is considered a TAP and what is a DOUBLE TAP (0-255)
  adxl.setTapThreshold(50);           // 62.5 mg per increment
  adxl.setTapDuration(15);            // 625 μs per increment
  adxl.setDoubleTapLatency(80);       // 1.25 ms per increment
  adxl.setDoubleTapWindow(200);       // 1.25 ms per increment

  // Set values for what is considered FREE FALL (0-255)
  adxl.setFreeFallThreshold(7);       // (5 - 9) recommended - 62.5mg per increment
  adxl.setFreeFallDuration(30);       // (20 - 70) recommended - 5ms per increment

  // Setting all interupts to take place on INT1 pin
  //adxl.setImportantInterruptMapping(1, 1, 1, 1, 1);     // Sets "adxl.setEveryInterruptMapping(single tap, double tap, free fall, activity, inactivity);"
                                                        // Accepts only 1 or 2 values for pins INT1 and INT2. This chooses the pin on the ADXL345 to use for Interrupts.
                                                        // This library may have a problem using INT2 pin. Default to INT1 pin.

  // Turn on Interrupts for each mode (1 == ON, 0 == OFF)
  adxl.InactivityINT(1);
  adxl.ActivityINT(1);
  adxl.FreeFallINT(1);
  adxl.doubleTapINT(1);
  adxl.singleTapINT(1);

//attachInterrupt(digitalPinToInterrupt(interruptPin), ADXL_ISR, RISING);   // Attach Interrupt

}

/****************** MAIN CODE ******************/
/*     Accelerometer Readings and Interrupt    */
void loop(){

  // Accelerometer Readings
  int x,y,z;
  adxl.readAccel(&x, &y, &z);         // Read the accelerometer values and store them in variables declared above x,y,z

  // Output Results to Serial
  /* UNCOMMENT TO VIEW X Y Z ACCELEROMETER VALUES */
  Serial.print(x);
  Serial.print(", ");
  Serial.print(y);
  Serial.print(", ");
  Serial.println(z);

//  ADXL_ISR();
  // You may also choose to avoid using interrupts and simply run the functions within ADXL_ISR();
  //  and place it within the loop instead.
  // This may come in handy when it doesn't matter when the action occurs.

}

/********************* ISR *********************/
/* Look for Interrupts and Triggered Action    */
void ADXL_ISR() {

  // getInterruptSource clears all triggered actions after returning value
  // Do not call again until you need to recheck for triggered actions
  byte interrupts = adxl.getInterruptSource();

  // Free Fall Detection
  if(adxl.triggered(interrupts, ADXL345_FREE_FALL)){
    Serial.println("*** FREE FALL ***");
    //add code here to do when free fall is sensed
  }

  // Inactivity
  if(adxl.triggered(interrupts, ADXL345_INACTIVITY)){
    Serial.println("*** INACTIVITY ***");
     //add code here to do when inactivity is sensed
  }

  // Activity
  if(adxl.triggered(interrupts, ADXL345_ACTIVITY)){
    Serial.println("*** ACTIVITY ***");
     //add code here to do when activity is sensed
  }

  // Double Tap Detection
  if(adxl.triggered(interrupts, ADXL345_DOUBLE_TAP)){
    Serial.println("*** DOUBLE TAP ***");
     //add code here to do when a 2X tap is sensed
  }

  // Tap Detection
  if(adxl.triggered(interrupts, ADXL345_SINGLE_TAP)){
    Serial.println("*** TAP ***");
     //add code here to do when a tap is sensed
  }
}