Using shiftin() and shiftout() with the same circuit - what to consider? I am designing a smart (or at least I hope so) onboard bicycle light system. The system will have an Arduino (currently prototyping with UNO) and a subsystem composed of a "panel" of buttons and leds.

This panel should stay at the handlebar, connected by multi-wire cable to the Arduino located elsewhere on the bicycle.

In order to read an arbitrary number of push-buttons, I plan to use CD4021 IC with shiftIn() function. And, in order to turn an arbitrary number of leds on and off, I plan to use 74HC595 IC and the shiftOut() function.

My doubts are: what should I consider in order to do so?

How many wires should I need to connect an arduino to the panel circuit containing the ICs? I believe it is 8 wires (two for the power, three for shifting in [latch, clock, data], and three for shifting out), right?
Can I use any pin I want? Or is it required to use specific pins?
Is that the "right way" of doing this? Any suggestion or improvement is welcome!

I have a post here about using an I2C 16-port port-expander: http://www.gammon.com.au/forum/?id=10945

That would use 4 wires for I2C (power, ground, SDA, SCL) or there is an SPI version which would require an extra wire (power, ground, SCK, MOSI, MISO).

I'm not sure about noise over your cable runs, on a bicycle presumably electrical noise is low, so either one might suit. This is the chip that  Ignacio Vazquez-Abrams mentioned in his comments. Any of the 16 ports can be configured as inputs or outputs as you desire, plus it can raise an interrupt on a change on an input pin.

You might find that the maximum current limits for output may not be adequate for your LEDs (the datasheet says maximum of 25 mA per output pin, plus a maximum of 125 mA for the whole chip). You could work around this with driver transistors on the chip output, but this is more complexity.

There are higher-powered shift registers (eg. TPIC6B595) which can handle more per pin than the 74HC595.

  Can I use any pin I want? Or is it required to use specific pins?

If you want to use I2C there are two specific pins dedicated to the I2C hardware. If you want to use SPI there are dedicated hardware pins as well (different ones) but you can also "bit-bang" SPI if you want.

See:

http://www.gammon.com.au/i2c

http://www.gammon.com.au/spi

  Is there a through-hole version of that?

All the chips I mention here have through-hole versions.


Return value of 0 if value is less than zero Background: I am using an analog pressure sensor with a range from 0-100PSI returning voltage values .44v to 4.44v. It's open air (or 0 PSI) voltage on the signal pin is .47 volts. I have a function that subtracts that .47v (to make zero) and then multiplies it by 25 (25 PSI per volt). Due to signal noise or other factors, sometimes my function returns a negative number, which wreaks havoc on my math. I would like to return a value of 0 when my offset math returns a negative number, but I'm having a problem with it.

The code that I wrote that doesn't work:

double EngineOilPressure() {
    //insert oil pressure code here
    int reading = analogRead(sensorPin3);
    float voltage = reading * 5.0;
    voltage /=1024.0;

    Serial.print(voltage); Serial.println(" volts");

    if (voltage-.47 < 0)
    {
        float voltadj = 0;
    }
    else
    {
        float voltadj = (voltage-.47);
    }

    float pressureP = voltadj * 25;
    return PSIToPascal(pressureP);
}

The error that I get is

dynamic_engine.pde: In function 'double EngineOilPressure()':
dynamic_engine.pde:41:23: error: 'voltadj' was not declared in this scope
Error compiling.

The code that works but sometimes returns a very wrong value:

double EngineOilPressure() {
    int reading = analogRead(sensorPin3);
    float voltage = reading * 5.0;
    voltage /=1024.0;

    Serial.print(voltage); Serial.println(" volts");

    float pressureP = (voltage - .47) * 25;
    return PSIToPascal(pressureP);
}

The scope of each of the two different and unrelated voltadj variables that your code (as below) declares is limited to within its enclosing set of braces.

if (voltage-.47 < 0)
{
    float voltadj = 0;
}
else
{
    float voltadj = (voltage-.47);
}

Instead perhaps say

float voltadj = voltage-.47;
if (voltadj < 0) voltadj = 0;

or perhaps

float voltadj = voltage < .47? 0 : voltage-.47;

or

float voltadj = constrain(voltage-0.47, 0.0, 5.0);

or

float voltadj = max(0.0, voltage-0.47);

Also see max() and constrain() reference pages at arduino.cc.


Can I control Arduino functions via PWM? I want to control small functions from an Arduino, things like moving servos or toggling lights. The purpose of these is to decrease the number of channels on a rover I'm constructing.

Using the PWM output of a channel from the receiver of the rover, can I assign certain pulse widths to functions the Arduino can perform? Thank you for reading, even if I sound a little inexperienced.

A filter and ADC should solve communication problem. However, UART would be much better.


PWM pins weird on Arduino Mega, works on Arduino Uno I've bought one of those cheap 2.4" TFT LCD resistive touchscreens, one of these:

It works great on my Arduino Uno, using the code from this github repository.  Now I'm trying to get this to work on my Arduino Mega.

On the Arduino Uno, the LCD controller data lines are configured as:

data[0:7] = PORTB[0:1] | PORTD[2:7]

ie. data pins 8, 9, 2, 3, 4, 5, 6, 7 make up the LCD controller data lines.

On the Mega, the pin numbers are the same but the ports are configured differently, so that:

data[0:7] = ((PORTH >> 5) & 0x03)
   | ((PORTH << 3) & 0xc0)
   | ((PORTG >> 1) & 0x10)
   | ((PORTE >> 2) & 0x0C)
   | ((PORTE << 2) & 0x20)

I've rewritten the TFTLCD::read8 and TFTLCD::write8 functions accordingly.

The screen doesn't work, though.  I've cut example code down to just resetting the LCD controller and reading the chip ID register, ie:

Tft.writeData(0);
Tft.writeData(0);
Tft.writeData(0);
Tft.writeData(0);

Tft.writeCommand(0);
unsigned id = Tft.readData();

Now, 9 times out of ten, this obtains the correct device ID, 0x9325.  But the other time, it obtains the device ID of 0.

I initially suspected that this was due to the Mega running somewhat faster, but liberally sprinkling delayMicroseconds(10) through the writeData, writeCommand and readData functions doesn't seem to make any difference.

Is there something that I'm missing that is messing with the use of the PWM lines on the Arduino Mega as ordinary digital port pins?

Never mind; this was me making a mess of the bit masking.

See this github repository for working code with Arduino Mega.


Arduino USB host + RS232 I'd like to get a word of advice regarding the subject. Basically there's a COM port based device which I need to connect to an Android tablet via USB. The tablet will be exchanging data packages with the COM device, but a) Arduino may need to do same transformation of the packages b) the tablet should not leverage OTG feature and shouldn't be a master itself.

So, my questions are

1) Which Arduino board is the best fit?
2) Is it an option to use Chinese boards for the sake of cost optimization?
3) Do I need separate RS232 and USB shield or it's ok to leverage built in USB and data pins?

Apology for this quite a noob question but that's exactly who I am for Arduino platform. Appreciate any answers.

1) Which Arduino board is the best fit? 2) Is it an option to use Chinese boards for the sake of cost optimization? 3) Do I need separate RS232 and USB shield or it's ok to leverage built in USB and data pins?

When communicating with Android you need to make sure that there is software available for doing the communication. That's really down to the application more than the operating system, and because of that it can be quite restricted what boards will work and what won't.

Personally I would go for either an ATMega32U4 based board which provides a standard CDC/ACM interface. This also has the advantage that the (often single) UART on the board is not used by the USB communication.

Then you need to convert the UART into RS232 using (for example) a MAX232 board.


How to include Vref in thermistor temperature calculation? simulate this circuit – Schematic created using CircuitLab
This is the code that I'm using to get the temperature:
#define COEFF_A 0.8662984364E-03
#define COEFF_B 2.780704551E-04
#define COEFF_C -0.9395108479E-07

float VRT, Temp;
float Vref = 2.52;

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

void loop() {
  long Resistance;
  VRT = analogRead(A3);
  Resistance = 10000 / ((1023.0 / VRT) - 1);
  Temp = log(Resistance);
  Temp = 1 / (COEFF_A + (COEFF_B * Temp) + (COEFF_C * pow(Temp, 3)));
  Temp += -273.15;
  Serial.println(Temp);
  delay(500);
}

I know that the calculation should be: V = Vref × VRT ÷ 1023 but i don't know how to implant it in this code, any help appreciated.

Update
After Edgar Bonet answer, the edited code is:
#define COEFF_A 0.8662984364E-03
#define COEFF_B 2.780704551E-04
#define COEFF_C -0.9395108479E-07

float VRT, Temp, VR;

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

void loop() {
  long Resistance;
  VRT = analogRead(A3);
  VR = 2.52 * VRT / 1024;
  Resistance = 10000 * VR / (2.52 - VR);
  Temp = log(Resistance);
  Temp = 1 / (COEFF_A + (COEFF_B * Temp) + (COEFF_C * pow(Temp, 3)));
  Temp += -273.15;
  Serial.println(Temp);
  delay(500);
}

But the temperature reading is 2 centigrade less than what it should be, when i remove the analogReference(EXTERNAL); it shows the normal/correct temperature readings.

The formula to get the analog voltage from the ADC reading is:

    V = Vref × reading ÷ 1024

(yes, it's 1024, not 1023). The formula to get the thermistor resistance
from the measured voltage is:

    R = Rref × V ÷ (Vref − V)

where Rref is your 10 kΩ pull-up. You can combine these
two formulas in order to get the resistance directly from the ADC
reading:

    R = Rref × reading ÷ (1024 − reading)

You may notice that, while doing this simplification, Vref
cancels out. It's not an error. The readings you get with this setup are
indeed independent of your reference voltage.

Update 1: After the OP's edit, we now have a completely different
question. The question is now: how come the readings do depend on the
reference voltage that is used, whereas in theory they should not.

The answer lies most likely in the ADC calibration. If high accuracy is
a requirement, the correct formula for the measured voltage is

    V = Vref ×
(reading + Eoff) ÷ (1024 + Egain)

where Eoff and Egain are the offset error and the
gain error respectively. These errors are not knows a priori, and they
are usually neglected when the accuracy requirement is low. The
datasheet only gives constraints on how big these errors can be. The
actual values depend on the specific microcontroller and can somewhat
depend on the reference voltage. The only solution to get rid of these
errors is to calibrate your own ADC. See Response of the Arduino
ADC for an example on how this could be done.

Update 2: If I had to program this in an Arduino, I would rather
simplify the calculations as much as possible before coding:

do not compute the measured analog voltage, nor the resistance, as
they are not needed
compute instead the ratio R/Rref directly from the analog
reading
rewrite the calibration polynomial as a function of
log(R/Rref) instead of log(R) (which actually means
log(R/(1 Ω)))
optimize the evaluation of the polynomial by using
Horner's method.

With these optimizations, we get:

// Coefficients of polynomial fit of log(R/Rref) -> 1/T.
const float c0 = 3.3540165e-3;
const float c1 = 2.5416075e-4;
const float c2 = -2.5959644e-6;
const float c3 = -9.3951087e-8;

// Convert ADC reading to temperature in deg. C.
static float temperature(int reading)
{
    float R_ratio = reading / (1024.0 - reading);  // = R / Rref
    float x = log(R_ratio);
    float inverse_T = c0 + x*(c1 + x*(c2 + x*c3));
    return 1/inverse_T - 273.15;
}

void loop()
{
    int reading = analogRead(A3);
    Serial.println(temperature(reading));
    deay(500);
}


Is there any way to use a JTAG programmer with the Arduino IDE? I am doing a lot of work with custom boards I've designed with the ATSAMD21G. I'd like to get away from using USB to program my boards since the USB port takes up space on the PCB and consumes extra pins. Is there any recommended way to configure the Arduino IDE to simply dump out the compiled program into a JLink debugger, much like the Atmel Studio IDE can?

For a one-click upload, you can make a custom hardware definition that calls any executable of your choosing.


Can LilyPad Main Board interface with a sensor via UART? Is the LilyPad Arduino Main Board physically capable of interfacing with, let's say, a LeddarTech LeddarOne Optical Rangefinder, which has a 3.3v UART interface? I understand that the LilyPad has a serial interface, but I wouldn't be sure if it was meant to handle more than just transferring code.

Yes you can.

Lilypad <> Other device using UART

Rx         <    Tx

Tx         >    Rx

Note that you cannot use 5V with the lilypad if you do this. If you do want to use 5V with the Arduino, then you'll have to put a voltage divider between the Tx and Rx (other wise you might fry the other UART device using 3.3V.

Also, when you upload the code FROM your computer TO your Lilypad, you have to connect all other UART device connected to the Lilypad. Connecting other devices to the Tx and Rx of the Lilypad while uploading a code to it might cause lag or bugs.

Hope I anwsered your question!


Adding to the counter only ONCE while R2 =<200 I am very new to Arduino and I have this little bit of code:

if (R2 <= 200){
  counter=counter+1;
  Serial.print("counter: ");
  Serial.println(counter);
}

I want it to count every time R2 is less than or equal to 200, but I only want it to count once. Right now it adds to the counter 3-2 times while R2 is less than 200. I'd like it to only count once while in that range before R2 becomes greater than 200.

Any suggestions or links to helpful information would be very appreciated. Thank you!

You can set a flag to indicate that R2 is or has been above 200 since it last was low, much as follows.

// before loop() ...
byte Rhi = true;  // at outset, say that R2 has been high
...

// in loop() ...
  if (R2 > 200)          // Has R2 gone high?
    Rhi = true;
  if (Rhi && R2 <= 200){ // Has R2 gone low from high?
    Rhi = false;
    ++counter;
    Serial.print("counter: ");
    Serial.println(counter);
  }
  ...


Communication between IC and microcontroller (Teensy 3.2) I am trying to use a rotary encoder with an integrated circuit to measure the position of a rotating shaft. I am then taking this data and writing to an SD card. The IC seems to be working correctly and outputting binary data to the specified pins,  but the data does not seem to be reaching the micro-controller. My output data is fragmented, and seems to only be receiving binary data from some of the IC pins. The IC I am using is HCTL-2021-A00 (http://www.mouser.com/ProductDetail/Avago-Technologies/HCTL-2021-A00/?qs=RuhU64sK2%252bsgeK17XZB%2fNA%3d%3d). I tried using a larger gauge wire to connect the two, but then the micro-controller didn't seem to pick up any of the data. Here is the code I used.

I am trying to use a rotary encoder with the HCTL-2021-A00 from avago. I am getting data output from the IC, but only one of the two bytes which it should be providing. When I move the encoder forward, it will only give me the LOW byte and all of the high bits will be zero. However, when I move the encoder backward, all of the high data bits are 1, and the low data bits still operate normally, counting the position. What could cause the high data bits to all be 1 when moving backward, and all 0 when moving forward? Code used is below.

#include <SD.h>
#include<SPI.h>

File datafile;
const int chipSelect = 10; // connected to the CS pin on the sd card, Make sure the card is formatted
int encoderpos=0;
int i=0;
int pulses, A_SIG=0, B_SIG=1;
int b[15];  //the individual bits of data read from the IC
int pos; //position output of IC ranging from 0 to 5000 for 1 revolution
int selpin=1, OEpin=2;
int clock=4;
int d[7]; //the pins on the IC attached to which digital teensy pins
double deg; //degree position of the servo as found from the encoder and IC

void setup()
{
  //set pwm signal for timer input
  pinMode(4, OUTPUT);
  analogWriteFrequency(4, 6000000); // Teensy 3.0 pin 3 also changes to 375 kHz
analogWrite(4, 128);
   //First setup and attach the pins used to communicate with the IC and encoder
  d[0]=22;//pin numbers for attaching the IC to the teensy
  d[1]=21;
  d[2]=20;
  d[3]=19;
  d[4]=18;
  d[5]=17;
  d[6]=16;
  d[7]=15;
//first set pins as inputs and outputs
pinMode(selpin, OUTPUT);
pinMode(OEpin, OUTPUT);
pinMode(d[0], INPUT);
pinMode(d[1], INPUT);
pinMode(d[2], INPUT);
pinMode(d[3], INPUT);
pinMode(d[4], INPUT);
pinMode(d[5], INPUT);
pinMode(d[6], INPUT);
pinMode(d[7], INPUT);

digitalWrite(selpin, HIGH);
digitalWrite(OEpin, HIGH);

pinMode(5, OUTPUT);

digitalWrite(5, HIGH);
delay(5);
digitalWrite(5, LOW);
delay(5);
digitalWrite(5, HIGH);
delay(5);

pinMode(chipSelect, OUTPUT);
SD.begin();
datafile=SD.open("c.txt", FILE_WRITE);
pinMode(7, INPUT);
pinMode(8, OUTPUT);

}

void loop()
{
datafile.println(pose());
if (millis()>4000)
{
  datafile.close();
}

delay(5);
}

int pose()     //Gives the position in degrees from the readings from encoder and IC for 0 to 5000 representing one revolution
{
    digitalWrite(selpin, LOW);     // The sel pin on the IC
  digitalWrite(OEpin, LOW);     // The OE pin on the IC
digitalWrite(4, HIGH);
digitalWrite(4, LOW);
analogWrite(4, 128);

  b[0]=digitalRead(d[0]);
  b[1]=digitalRead(d[1]);
  b[2]=digitalRead(d[2]);
  b[4]=digitalRead(d[4]);
  b[5]=digitalRead(d[5]);
  b[6]=digitalRead(d[6]);
  b[7]=digitalRead(d[7]);
if(digitalRead(7)==1)
{
  digitalWrite(8, HIGH);
}
else if(digitalRead(7)==0)
{
  digitalWrite(8, LOW);
}
  digitalWrite(selpin, HIGH);
digitalWrite(4, HIGH);
digitalWrite(4, LOW);
analogWrite(4, 128);

  b[8]=digitalRead(d[0]);
  b[9]=digitalRead(d[1]);
  b[10]=digitalRead(d[2]);
  b[11]=digitalRead(d[3]);
  b[12]=digitalRead(d[4]);
  b[13]=digitalRead(d[5]);
  b[14]=digitalRead(d[6]);
  b[15]=digitalRead(d[7]);

  digitalWrite(OEpin, HIGH);

  pos=0;
  i=8;
  for(i; i>0; i--)
  {
pos=2*pos+b[i-1];
  }

  i=16;
  for (i; i>8; i--)
  {
    pos=2*pos+b[i-1];
  }

  return pos;

}

You seem to be overlooking (or at least mishandling) the fact that these parts are built with a bus interface where the /OE and SEL signals as well as the internal position data latch are sampled synchronously with a clock input which you do not seem to be driving.

You need to generate a low-to-high transition of the CLK signal to latch the count into the readout
You need to generate a high-to-low transition of the CLK signal to latch in chosen values of the /OE and SEL signals.

On second examination of your code, perhaps you are trying to use a free-running clock asynchronous to your reading.  That, however, is extremely unwise.  First, you don't know that a suitable clock edge will happen between when you set the /OE or SEL and when you try to read the data.  Next, you do not know that an undesired clock edge will not happen in the midst of reading data, causing you to end up with a corrupted value that contains some "old" bits from before the clock edge and some "new" bits from after.  This would be particularly bad if it happened across a transition such as 0b01111111 to 0b10000000 or similar...

You may have other problems as well - your question is not complete without a schematic diagram of how you have wired up this chip.


ESP8266 feather huzzah wiring for MFRC522 I'm trying to wire the mfrc522 and the huzzah but i can't seem to figure out the rst pin.

I found the pin out diagram but it doesn't show or idk how its labeled as.

use Wemos table from your link. here is the mapping to esp8266 io pins

RST/Reset   D3 = io 0
SPI SS      D8 = io 15
SPI MOSI    D7 = io 13
SPI MISO    D6 = io 12
SPI SCK     D5 = io 14

If you want, you can use any pin for SS and reset. See the examples.

#define SS_PIN 4
#define RST_PIN 5
MFRC522 mfrc522(SS_PIN, RST_PIN);


IR Remote code not activating ON/OFF states The code below is for turning RGB lights on/off. The connections are as indicated in pin numbers. I found the resulting value of the buttons of the remote but when I used them in code it is not showing ON/OFF.

I assume there may be some practical errors. How to avoid such errors?

#include <IRremote.h>

int RECV_PIN = 3;
int red = 13;
int blue = 12;
int green = 11;

IRrecv irrecv(RECV_PIN);

decode_results results;

void setup() {
  Serial.begin(9600);
  irrecv.enableIRIn(); // Start the receiver
  pinMode(red, OUTPUT);
  pinMode(blue, OUTPUT);
  pinMode(green, OUTPUT);
}

void loop() {
  if (irrecv.decode(&results)) {
    long int getting = results.value;
    Serial.println(getting);
  }
  switch (results.value) {
    case 16582903:
      digitalWrite(red, HIGH);
      digitalWrite(blue, LOW);
      digitalWrite(green, LOW);
      break;
    case 16615543:
      digitalWrite(red, LOW);
      digitalWrite(blue, HIGH);
      digitalWrite(green, LOW);
      break;
    case 16599223:
      digitalWrite(red, LOW);
      digitalWrite(blue, LOW);
      digitalWrite(green, HIGH);
      break;
    default:
      Serial.println("Enter ;");
  }
  irrecv.resume(); // Receive the next value
  delay(100);
}

Assuming you wiring is correct, the only mistake I could see is that your variable named "getting" used in switch is inside the if, and it should be at least in the same level of switch. Also, your resume needs to be inside the if.

#include <IRremote.h>

int RECV_PIN = 3;
int green = 11;
int blue = 12;
int red = 13;

#define code1  16582903 // Must match exactly the code generated by the IR button, would be something like 0xFF906F
#define code2  16615543
#define code3  16599223

IRrecv irrecv(RECV_PIN);
decode_results results;

void setup() {
  Serial.begin(9600);
  irrecv.enableIRIn(); // Start the receiver
  pinMode(red, OUTPUT);
  pinMode(blue, OUTPUT);
  pinMode(green, OUTPUT);
}

void loop() {
  if(irrecv.decode(&results)) {
    //this checks to see if a code has been received
    Serial.println(results.value, HEX);
    unsigned int getting = results.value;
    Serial.println(getting);
    switch (getting) {
      case code1:
        digitalWrite(red, HIGH);
        digitalWrite(blue, LOW);
        digitalWrite(green, LOW);
        break;
      case code2:
        digitalWrite(red, LOW);
        digitalWrite(blue, HIGH);
        digitalWrite(green, LOW);
        break;
      case code3:
        digitalWrite(red, LOW);
        digitalWrite(blue, LOW);
        digitalWrite(green, HIGH);
        break;
      default:
        Serial.println("Enter ;");
    }
    irrecv.resume(); //receive the next value
  }
  delay(100);
}


Trying to pass a char to software serial with a button press Good day everyone,
I'm returning to the Arduino world after my a 3 year hiatus following the birth of my son.

I'm trying to push a button connected to pin 2 and have that send a 'd' to SoftwareSerial on pins 10,11. This should trigger an output back from the device connected to the SoftwareSerial.

I'm encountering an issue:

When I press the button it sends about 15 d's. I would like to limit this to just one char per button press, I attempted to build an if statement but it seems to ignore the conditions.

#include <SoftwareSerial.h>
// software serial #1: TX = digital pin 10, RX = digital pin 11
SoftwareSerial portOne(10, 11);
const int buttonPin = 2;     // the number of the pushbutton pin
const int ledPin =  13;      // the number of the LED pin

// variables will change:
int buttonState = 0;         // variable for reading the pushbutton status
int button1State = 0;

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

  // Start each software serial port
  portOne.begin(4800);
  while (!portOne) {
    ; // wait for serial port to connect. Needed for native USB port only
  }
}

// the loop function runs over and over again forever
void loop() {
  int Once = 0;
  buttonState = digitalRead(buttonPin);

  // check if the pushbutton is pressed.
  // if it is, the buttonState is HIGH:
  if (buttonState == HIGH ) {
    if (Once == 0) {
      Once = 1;
      // turn LED on:
      digitalWrite(ledPin, HIGH);
      // send D to Radio
      portOne.write("d");
      Serial.write("d");
      Serial.print(Once);
      Serial.println();
      delay(1);
    }
  }
  else (buttonState == LOW) {
    // turn LED off:
    Once = 0;

    digitalWrite(ledPin, LOW);

  }
  portOne.listen();
  // while there is data coming in, read it
  // and send to the hardware serial port:
  while (portOne.available() > 0) {
    char inByte = portOne.read();
    Serial.print(inByte);
  }
}

As pointed out by Edgar you should debounce the button. Perhaps increasing the delay() should do the trick.

Try with 100-200 milliseconds.

With this edit you can delete Once unless you are planning on using it somewhere else.


NodeMCU 1.0 - Exception 9 `Fatal exception 9(LoadStoreAlignmentCause):` I am getting this error in my code.
Fatal exception 9(LoadStoreAlignmentCause):

Using core version 2.4.2

Stack trace

Decoding stack results
0x40213e9c: dns_gethostbyname at core/dns.c line 1472
0x40204c21: ESP8266WiFiGenericClass::hostByName(char const*, IPAddress&, unsigned int) at /home/tony/.arduino15/packages/esp8266/hardware/esp8266/2.4.2/libraries/ESP8266WiFi/src/ESP8266WiFiGeneric.cpp line 468
0x40205038: WiFiClient::connect(char const*, unsigned short) at /home/tony/.arduino15/packages/esp8266/hardware/esp8266/2.4.2/libraries/ESP8266WiFi/src/WiFiClient.cpp line 98
0x4020306b: setPostString(int, int, Array8Int, char*) at /home/tony/Arduino/sketches/tempo1_vs11e_Master_NodeMCU_Rain_Wind/tempo1_vs11e_Master_NodeMCU_Rain_Wind.ino line 516
0x40203f8a: uploadAgrigis(char const*) at /home/tony/Arduino/sketches/tempo1_vs11e_Master_NodeMCU_Rain_Wind/tempo1_vs11e_Master_NodeMCU_Rain_Wind.ino line 335
0x40209080: Print::println() at /home/tony/.arduino15/packages/esp8266/hardware/esp8266/2.4.2/cores/esp8266/Print.cpp line 178
0x402048e0: loop() at /home/tony/Arduino/sketches/tempo1_vs11e_Master_NodeMCU_Rain_Wind/tempo1_vs11e_Master_NodeMCU_Rain_Wind.ino line 243

struct declaration

struct Array8Int {
    int array[8];
};

loop

char post[300] = "";
int pulseChange05m = rainCheck(slaveData);
int now10 = floor(unixtimeServer/10)*10;
Array8Int slaveData = slaveCheck(now()); // update slaveData array
setPostString(now10, pulseChange05m, slaveData, post);

functions

void setPostString(int unixtimeEvent, int pulseChange, Array8Int postData, char* postStr) {
  bool flag = true;
  float rainHour = pulseChange*0.25;
  if (hour() == 10) { // 7 AM palmital
    rainCount = 0;
    rainCount05m = 0;
  }
  rainCountHour = rainCount;
  int humidityBme280HourAvg = 0;
  int pressureBme280HourAvg = 0;
  int temperatureBme280HourAvg = 0;
  int lightSensorHourAvg = 0;
  int pressureBme280HourMin = 100000;
  int temperatureBme280HourMin = 1000;
  int temperatureBme280HourMax = -1000;
  int counterLoop = counterHour;
  for(int i=0;i<counterLoop;i++) {
    lightSensorHourAvg += lightSensorHour[i];
    pressureBme280HourAvg += pressureBme280Hour[i];
    temperatureBme280HourAvg += temperatureBme280Hour[i];
    temperatureBme280HourMax= max(temperatureBme280HourMax,temperatureBme280Hour[i]);
    pressureBme280HourMin = min(pressureBme280HourMin,pressureBme280Hour[i]);
    temperatureBme280HourMin = min(temperatureBme280HourMin,temperatureBme280Hour[i]);
    humidityBme280HourAvg += humidityBme280Hour[i];
  }
  pressureBme280HourAvg = pressureBme280HourAvg/counterLoop;
  temperatureBme280HourAvg = temperatureBme280HourAvg/counterLoop;
  lightSensorHourAvg = (int)lightSensorHourAvg/counterLoop;

  strcat(postStr, stationId);
  strcat(postStr,"&3="); // chuva hora
  strcat(postStr, dtostrf(rainHour,6,2,charDummy));
  strcat(postStr,"&8=");
  strcat(postStr, dtostrf(temperatureBme280HourAvg,6,2,charDummy));
  strcat(postStr,"&9="); //temperature avg
  strcat(postStr, dtostrf(temperatureBme280HourAvg,6,2,charDummy));
  strcat(postStr,"&10="); //temperature avg
  strcat(postStr, dtostrf(temperatureBme280HourMax,6,2,charDummy));
  strcat(postStr,"&11="); //temperature avg
  strcat(postStr, dtostrf(temperatureBme280HourMin,6,2,charDummy));
  strcat(postStr,"&20=");
  strcat(postStr, dtostrf(pressureBme280HourAvg,10,0,charDummy));
  strcat(postStr,"&22=");
  strcat(postStr, dtostrf(pressureBme280HourMin,10,0,charDummy));
  strcat(postStr,"&101=");
  strcat(postStr, dtostrf(lightSensorHourAvg,6,0,charDummy));
  strcat(postStr,"&time=");
  strcat(postStr, dtostrf(unixtimeEvent,16,0,charDummy));
  strcat(postStr,"&endline=1");
  strcat(postStr, "\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n");
}
int rainCheck(Array8Int slaveData) {
  int pulseChange = slaveData.array[0];
  return pulseChange;
}

Fatal exception 9(LoadStoreAlignmentCause):

This is caused by you (or some code you are running) attempting to read or write a 32 bit value from memory that is not "aligned" to 32 bits.  It is most often the result of trying to cast portions of a byte array (for instance a buffer received over UDP) to a 32-bit integer.  The compiler is not clever enough to know that the byte array portion you are casting isn't at a 32-bit boundary and thus doesn't know to use the 8-bit load/store instructions to access the memory.

Mapping a struct over a buffer can also have similar issues where the buffer is 8-bit aligned and the struct contains 32-bit words.

You can combat it by forcing the alignment of any buffers which you treat in such a way with the __attribute__((aligned(4)) tag:

uint8_t __attribute__((aligned(4))) buffer[128];

You can also "pack" structures to tell the compiler "These variables are mis-aligned and should not be padded to 32-bits":

struct foo {
    uint8_t bar1;
    uint32_t bar2;
} __attribute__((packed));

If in doubt, though, just pull individual bytes out of buffers (or wherever) and build up your larger integers manually with bit shifting and OR operators (<< and |), and do the reverse for filling byte buffers.


Extend program space by getting rid of bootloader on NANO I just have a complex program that runs on a NANO. Now when I use my printlns for debugging I am running out of memory.
I read about using a programmer to get rid of the bootloader that uses 2K space on a NANO. I bought an USBTinyIsp and got it to work successfully... almost I can program the nano as I wanted, but I do not get any additional space.
When programming with debug printlns I run into the same message as before which states the same maximum space within (I guess it was 30700).
Why is this the case? I thought the bootloader gets overridden when using a programmer and so frees 2K of programmable space.
Please note: I am not asking how to optimize my program code! Thank you for taking notice ;)
Thank you very much.

It's enforcing this line from the arduino:avr boards.txt
nano.menu.cpu.atmega328.upload.maximum_size=30720

To be clear, the board is assumed to have a bootloader, even if you're not using it to get the code onto the board, that is upload via programmer.
You could edit that and change some fuses yourself.  But you could also probably just use MCUdude MiniCore, choosing an option that does not use a bootloader, e.g. ATmega328P with No bootloader, which gives you maximum upload of 32768:
328.menu.bootloader.no_bootloader.upload.maximum_size=32768

Keep in mind that in either case you'll have needed to set the fuses for not having a bootloader.  As weird as this sounds, choosing the No Bootloader option in MCUdude MiniCore for the ATmega328P, and then doing Burn Bootloader sets these fuses for you, despite the name not actually burning a bootloader in this case.  If you were to edit the maximum upload size for the Nano board, you would need to manually set the fuses similarly to what Burn "Bootloader" does for the MiniCore ATMega328P with No-bootlader option.


Save highlighted text as int variable I build a macro keyboard and one thing I do alot is add a set amount to numbers mostly in 3d modeling programs. I add and remove 0.25 and 0.125 all the time. I want to make a macro that copies selected text, adds or subtracts a value then pastes it back.
I known the simple copy and paste commands but how do I get my arduino program to grab that copied value?
Can this even be done?

You have to write an application for your PC that

reads a number from the clipboard
adds some constant
puts the result back in the clipboard
quits

Then you have to configure you desktop environment in order to have this
application launched from a keyboard shortcut.
Once you have done that, you can do the whole operation from a regular
keyboard: Ctrl-C + Launcher shortcut + Ctrl-V.
If you can do it from a regular keyboard, you can do it from the Arduino
emulating a regular keyboard.
Edit: The way you do the first two steps is very dependent on the OS
running on your PC. On Linux, for example, the mentioned “application”
can be a minimal shell script:
#!/bin/bash

x=$(xclip -o -selection clipboard)
xclip -i -selection clipboard <<< $(bc <<< "$x + 0.25")

These steps are, however, outside the scope of this site.


Converting array to char I'm trying to convert a char array to a char. i used this code

char code[4] = {'1','2','3','4'};

char strcode[4];

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

void loop()
{
    memcpy(strcode, code, 4);
    Serial.println(strcode);
    Serial.println("done");
    delay(1000);
}

But for some reason when i read my serial monitor i get this:

1234
done

Why are there 2 squares behind it?  Am I doing it wrong?

EDIT: For some reason stackexchange doesn't show the 2 squares but there are 2 squares behind 1234

C strings need to be NUL-terminated.

char strcode[5];

 ...

 ...
     ...
    strcode[4] = '\0';
     ...


Using more than 8 digits using the sevseg library I am using sevseg and i can't get more than 8 digits to work.  I really need 15.  Does somebody know what I can do to get this?

Shown is the original example

This is using Gabriel Staples example in the sevseg library:

#include <SevSeg.h>

SevSeg sevseg; //Instantiate a seven segment controller object

void setup()
{
  byte numDigits = 4; //<<---I am wanting 15, but doesn't work after 8------
  byte digitPins[] = {2, 3, 4, 5}; //Digits: 1,2,3,4 <--put one resistor (ex: 220 Ohms, or 330 Ohms, etc, on each digit pin)
  byte segmentPins[] = {6, 7, 8, 9, 10, 11, 12, 13}; //Segments: A,B,C,D,E,F,G,Period

  sevseg.begin(COMMON_ANODE, numDigits, digitPins, segmentPins);
// Note: 100 brightness simply corresponds to a delay of 2000us after lighting each segment. A brightness of 0
// is a delay of 1us; it doesn't really affect brightness as much as it affects update rate (frequency).
// Therefore, for a 4-digit 7-segment + pd, COMMON_ANODE display, the max update rate for a "brightness" of 100 is 1/(2000us*8) = 62.5Hz.
// I am choosing a "brightness" of 10 because it increases the max update rate to approx. 1/(200us*8) = 625Hz.
// This is preferable, as it decreases aliasing when recording the display with a video camera....I think.
  sevseg.setBrightness(10);
}

void loop()
{
  //local vars
  static byte decPlace = 0;

  sevseg.setNumber(8888,decPlace);
  decPlace++;
  decPlace %= 4; //rollover back to 0 once variable gets to 4; To anyone wondering: the % is called the "modulo" operator; see here for explanation & example: https://www.arduino.cc/en/Reference/Modulo

  sevseg.refreshDisplay(); // Must run repeatedly; don't use blocking code (ex: delay()) in the loop() function or this won't work right
}

Using the following code, I can't get the 3rd set of 5 numbers to display.  I have changed the sevseg.h file to 15, but that shouldn't matter:

#include <SevSeg.h>

SevSeg sevseg1;//Instantiate a seven segment controller object 1
SevSeg sevseg2;//Instantiate a seven segment controller object 2
SevSeg sevseg3;//Instantiate a seven segment controller object 3

void setup()
{

  Serial.begin(9600);

byte segmentPins[] = {22, 23, 24, 25, 26, 27, 28, 34}; //Segments:     A,B,C,D,E,F,G,Period

  byte digitPins1[] = {29, 30, 31, 32, 33};
  sevseg1.begin(COMMON_CATHODE, sizeof(digitPins1), digitPins1,  segmentPins);
  sevseg1.setBrightness(10);

  byte digitPins2[] = {35, 36, 37, 38, 39};
  sevseg2.begin(COMMON_CATHODE, sizeof(digitPins2), digitPins2, segmentPins);
  sevseg2.setBrightness(10);

  byte digitPins3[] = {40, 41, 42, 43, 44};
  sevseg3.begin(COMMON_CATHODE, sizeof(digitPins2), digitPins3, segmentPins);
  sevseg3.setBrightness(10);

}

void loop()
{

static byte decPlace = 2;

  sevseg1.setNumber( 12345, decPlace );
  sevseg2.setNumber( 12345, decPlace );
  sevseg3.setNumber( 12345, decPlace );

  sevseg1.refreshDisplay();
  sevseg2.refreshDisplay();
  sevseg2.refreshDisplay();
}

You can change the pre-defined maximum number of digits at the top of the SevSeg.h header file to as many as 10, if you use long or unsigned long when you call setNumber.  It is defined here, on line 27:
#define MAXNUMDIGITS 8 //Increase this number to support larger displays

This the version referenced from the Arduino Playground SevSeg.  Be sure to use the same number in your modulo, too:
void loop()
{
  //local vars
  static byte decPlace = 0;

  sevseg.setNumber(8888,decPlace);
  decPlace++;
  decPlace %= 10; //rollover back to 0 once variable gets to 10

decPlaces is mostly useful for floating-point numbers: it specifies how many digits after the decimal point should be displayed.  For integer values, it specifies how many leading zeroes will be displayed.
However (as you discovered), you cannot call setNumber with anything larger than a long, so you are limited to 10 or fewer digits for MAXNUMDIGITS.  (There is no byte overflow -- it's just limited to the number of decimal digits in 232-1.)  This is a limit of one SevSeg instance.  You could have two instances of SevSeg like this:
#include <SevSeg.h>
SevSeg sevseg1;
SevSeg sevseg2;

void setup()
{
  byte segmentPins[] = {6, 7, 8, 9, 10, 11, 12, 13}; //Segments: A,B,C,D,E,F,G,Period

  byte digitPins1[] = {2, 3, 4, 5, 22, 23, 24};
  sevseg1.begin(COMMON_ANODE, sizeof(digitPins1), digitPins1, segmentPins);
  sevseg1.setBrightness(10);

  byte digitPins2[] = {14,15,16,17,18,19,20,21};
  sevseg2.begin(COMMON_ANODE, sizeof(digitPins2), digitPins2, segmentPins);
  sevseg2.setBrightness(10);

  sevseg1.setNumber(  7654321UL, 7 );
  sevseg2.setNumber( 87654321UL, 8 );
}

void loop()
{
  sevseg1.refreshDisplay();
  sevseg2.refreshDisplay();
}

The first instance handles 7 digits, and the second instances handles 8 digits.  Note the use of "UL" to force and unsigned long call.
Update 11-DEC-2015

Using the following code, I can't get the 3rd set of 5 numbers to display. I have changed the sevseg.h file to 15, but that shouldn't matter:

First, the MAXNUMDIGITS is the maximum per instance, so you could set it to 5 to save some precious RAM.
Second, you have a copy and paste error:
sevseg1.refreshDisplay();
sevseg2.refreshDisplay();
sevseg2.refreshDisplay();   <--  Oopsies!  :)

Third, I assume the setNumber calls are placeholders for what you're really going to use.  Since they always set the same value, they could be in setup.  In your final program, there must be some input that will be used to calculate a number to display with setNumber.


Connect SD card to Arduino with or without a level shifter I have some audio files in an SD card and I want to play them using Arduino, thus connect the SD card to the Arduino. Since the transfer of the data will be from the SD card (+3.3V) to the Arduino (+5.0V) and not vice versa, is a level shifter necessary?

You can't use SD card without level conversion from 5 V to 3.3 V. Clock and CS line are driven by the master, and the master must request over MOSI the data to read.


Using HC-08 bluetooth module with arduino I have an arduino mega 2560 and a recently purchased HC-08 module and the connection is as the following:
Arduino | HC-08
VCC - VCC
GND - GND
14TX3 - TXD
15TX3 - RXD
When I power up the arduino it shows that flashing light and I am able to see it on my android phone but would only reject the connection every time I tried to pair. Also I am not able to send or receive any data from it at all, here is my code:
#include <SoftwareSerial.h>

SoftwareSerial hc08(15,14) // RX pin, TX pin;

void setup(){
  //Initialize Serial Monitor
  Serial.begin(9600);
  Serial.println("ENTER AT Commands:");
  //Initialize Bluetooth Serial Port
  hc08.begin(9600);
}

void loop(){
  //Write data from HC08 to Serial Monitor
  if (hc08.available()){
    Serial.println("Reading from bluetooth");
    Serial.write(hc08.read());
  }

  //Write from Serial Monitor to HC08
  if (Serial.available()){
    Serial.println("Writing to bluetooth");
    hc08.write(Serial.read());
  }
}

I'd really appreciate help on how to get it working.

void setup(){
  //Initialize Serial Monitor
  Serial.begin(9600);
  Serial.println("ENTER AT Commands:");
  //Initialize Bluetooth Serial Port
  Serial3.begin(9600);
}

void loop(){
  //Write data from HC08 to Serial Monitor
  if (Serial3.available()){
    Serial.println("Reading from bluetooth");
    Serial.write(Serial3.read());
  }

  //Write from Serial Monitor to HC08
  if (Serial.available()){
    Serial.println("Writing to bluetooth");
    Serial3.write(Serial.read());
  }
}


How to empty the buffer for Serial port? I have a Yun that accepts commands via the bridge (note the below code is part of a very simple virtual keyboard that accepts commands then runs Keyboard.println on them:

#include <stdlib.h>
#include <string.h>
HardwareSerial *port;

void setup() {
  port = &Serial1;
  port->begin(9600);
}

void loop() {
  if (port->available()) {
    String cmd = port->readString();

    if(cmd.length() > 1){
      String instruction = cmd;
      int arg_comma_index = 0;
      arg_comma_index = instruction.indexOf(",");
      String func = instruction.substring(0, arg_comma_index);
      String args = instruction.substring(arg_comma_index + 1, instruction.length() + 1 );

      Keyboard.begin();
      Keyboard.println(args);
      Keyboard.end();
    }
    port->read(); // Try to throw away whatever's left to prevent looping (which is still happening).
  }
}

If I send it a short string:

The first time, immediately after starting the sketch, it works.
The second time, it works but loops anywhere from 1-5 times.
The third time, it loops more times still.
If I leave the device running (even if not operating it), the number of times it loops goes up when I finally do send it an instruction. I'm seeing 20-75 loops after less than 15 minutes of uptime.

Clearly the loops where no instruction is being received are still building up something here. I've tried:

Restarting the port each void loop().
Flushing the port at the top and/or bottom of each void loop().
Setting cmd = "" at the end of each void loop().
Checking peek(), available(), and readString() - after I send it one instruction, they return the same values every single time they loop.

It's quite simple to empty the serial buffer - you just read all the data that is in the buffer and throw it away:

while (port->available()) {
    port->read();
}


Why does Serial.print print out the wrong thing? I am using a flame sensor. I am reading the state and then printing it. Here is my code:

void loop(){
 flameState = digitalRead(flamePin);//variables already defined and are global
existsFire();//calls the void
delay(1000);
}

void existsFire(){

Serial.println("Flame: " + flameState);

}

Before, this printed out the right thing. Today, it was printing out "lame:". The "F" and the flameState were missing. I changed it to:

void existsFire(){

Serial.print("Flame: ");
Serial.println(flameState);

}

Everything worked fine. Is there a problem with my Arduino Mega. What do I need to do to fix this?

You've stumbled across the difference in the C++ language between a String and an "array of characters". What you gave Serial.println() was an array of characters:

Serial.println("Flame: "...);

and then tried to add a number to it.

Serial.println("Flame: " + flameState);

If it had have been a String, then what you typed would have been fine:

String flame = "Flame: ";
Serial.println(flame + flameState);

Adding (literally +) a number to a String adds characters to the String to represent the number. Unfortunately you didn't start with a String, you started with an array of characters:

"Flame: "

Adding a number to THAT changes where the array starts. flameState must have been 1, and "Flame: " + 1 would have been "lame :" - as you found out!

The version that worked did so through a little bit of magic:

Serial.print("Flame: ");
Serial.println(flameState);

The first line called a version of print() that accepted an array of characters and printed each of them out. The second line called a different version of println() that accepted a number and printed out its representation as a series of characters (digits) - followed by a new line (the ln part of the name).


Passing a long string from SoftwareSerial to Serial I'm currently playing around with a GPRS shield on an Arduino Uno, for which I have to write raw AT commands over the SoftwareSerial. At the moment, I just want to be able to talk to the GPRS from my PC, so I've written a really basic program to send serial in two directions:

#include <SoftwareSerial.h>

SoftwareSerial GPRS(7, 8);

void setup()
{
  GPRS.begin(19200);
  Serial.begin(19200);
}

void loop()
{
  if (GPRS.available())
  {
    Serial.write(GPRS.read());
  }

  if (Serial.available())
  {
    GPRS.write(Serial.read());
  }
}

So the communication looks something like this:

         HW               SW
+----+ Serial +-------+ Serial +------+
|    |        |       |        |      |
|    +-------->       +-------->      |
| PC |        |Arduino|        | GPRS |
|    <--------+       <--------+      |
|    |        |       |        |      |
+----+        +-------+        +------+

This seems to work fine for shorter commands:

AT+CPIN?

+CPIN: READY

OK

But I'm really interested in doing a NETSCAN to see what networks are available. When I try it, I get this:

AT+CNETSCAN

------MOST SUITABLE CELL------
Operator:"YES OPTUS",MCC:505,75

And that's all. I pulled out a logic analyser to spy on the serial pins themselves, and it appears that the complete message is being sent back to the Arduino from the GPRS module perfectly okay - but for some reason, it gets cut off before it reaches my PC.

This is what the logic analyser sees over the SW (top two tracks) and HW (bottom tracks) serial lines:

So it appears that the entire GPRS response is being read by the Arduino before it starts to send anything back to the PC, and I assume that some sort of buffer has been overrun and I only get the start of the message.

So - how should I go about passing through long strings between serial ports like this? I assumed that using if (X.available()) instead of while would alleviate any issues with long strings (because it appears that this way the two serial ports should take turns with one byte at a time), but is that assumption incorrect?

The output of the logic analyser is pretty clear. The problem will be a buffer overflow. One question is whether it is the receive buffer or the send buffer.

My best guess is the receive buffer: What could go wrong with your code is that the interrupts used by SoftwareSerial take precedence over the ones used by HardwareSerial. So maybe that's the reason why nothing is sent before the full message is received.

The SoftwareSerial library has a debug flag (_DEBUG) which you can enable to pulse a pin as an overflow indictator.

What I would try is to swap Software- and HardwareSerial (i.e. use SoftwareSerial for the communication with the PC). If the problem is as described above it should then vanish because the HardwareSerial does not block interrupts (nor the program flow) while receiving a byte.


I'm looking for a real small but decent Arduino, that can fit in a watch but power a servo and a gyroscope I've been scouring the internet looking for a small Arduino that can power two sensors and a servo. Is there a way of getting a custom one? Does anyone know if theres software out there for creating custom Arduinos and having them made?

Look at the ATtiny85 MCU. It's a small 8pin device, and pretty easy to get up and running using Arduino code. You could also use the ATtiny84 which has more pins and still very small.

Start here: https://code.google.com/p/arduino-tiny/

Also, there are plenty of tutorials on setting up and programming them.

Regarding a custom board, your least expensive route would be to design your own. Otherwise you would need to outsource the design.


Measuring distance based on time I have written a arduino sketch which is used to measure the distance travelled. Since distance = speed * time , I have initiated speed = 6. I have initiated time = millis() variable and it calculates the time in millis().

So, distance is calculated as (speed*time) /1000 and we get distance for every second.

Now, as soon as the distance==20, I want to print distance and then delay for 5 seconds. So, as soon as distance==20 implies time = 4000 . If I delay for 5 seconds, time becomes 9000. But I want time to start from 4000 itself. So I have initiated another variable called curTime = time - prevTime.At the start, prevTime = 0. Code:

int prevTime = 0;
void loop(){
  unsigned long time = millis();
  unsigned long curTime = time - prevTime;
  int speed = 6;
  unsigned long distance = (speed * curTime)/1000;
  Serial.println(distance); // displays values of distance
  if(distance == 20){
    Serial.println(distance);
    delay(5000);
    prevTime = time;
  }
}

So prevTime = 4000 if distance == 20.
After this, time will be equal to 9000 and curTime will be 9000-4000 which equal 5000. So the distance will be 30 skipping all the values between 20 and 30. I don't want the distance to skip the values between 20 and 30. I have tried a lot but couldn't achieve it. Please help me fix this.

Thanks.

Link for code:

https://circuits.io/circuits/5260912-the-unnamed-circuit/edit

When distance == 20 you pause for 5 secs. So all calculations after that will be off by 5 secs. So, prevTime should equal 5000.

unsigned long time = millis();
unsigned long curTime = time - prevTime;    // 0 or 5000
int speed = 6;
unsigned long distance = (speed * curTime) / 1000; // calculating distance in meters for every milli second
Serial.println(distance);
// Only pause once
if (distance == 20 && prevTime == 0) {
  delay(5000);
  prevTime = 5000;  // Adjust for the delay
}


Find RSSI of Mobile Device Without Connecting I have a device in which a user connects their mobile device to an arduino uno via a HM-10 bluetooth transponder.  I want to be able to calculate the approximate distance between the user and the transponder by hopefully using the RSSI methodology:

 d = 10 ^ ((TxPower - RSSI) / 20)

My goal is for the user to send a connection request to the HM-10, the uno to then calculate the distance, and if greater than x meters away, reject the request.  I realize RSSI based distance is an estimate at best but that is fine for my purposes.

With that in mind, I have two questions:

1.) Is an HM-10 able to capture the RSSI strength of a mobile device to
    calculate distance?
2.) Can it do so WITHOUT connecting first based on the
    initial request of the mobile device?

You have two questions, but what makes you think you can't find these out?

When you want to know what a device can do (and thus can't do) you should check the devices' datasheet. I believe it is this file.

Bluetooth (and gsm) devices often work by sending AT commands. For example: "AT+PIO" to set/query GPIO pins of the module.
You can send "AT+RSSI?" to get a response on the RSSI value.

Not everything can be mentioned in the datasheet though. If you can't find any sources on it, it's most likely not a feature.

The only way to add a "validation function" within the bluetooth connection code, would be to re-write the firmware of the device.

But, you could:

Connect (with everyone using the right pin)
Check their RSSI
Disconnect if it doesn't match your criteria

I'm not sure if this module can have multiple connections, I didn't really see a way to disconnect a single connection. If not, you could even toggle the power to the module to "disconnect" the client(s).


how to implement PWM LED fading into a random case switch? Ive recently bought my self a arduino Mega 2560 and managed to get a sort of RANDOM function to work with different cases which go of by the number selected.
My question is is there a way to also make a PWM sequence in such a case? so that the LED is fully light to dark and then the the next case starts?  IS there a more random sequence wich i could then also expand if neccesary?

Mark.

int ledcolor = 0;
 int a = 500; //this sets how long the stays one color for
int b = 2000;
int brightness = 255;    // how bright the LED is
int fadeAmount = 25;    // how many points to fade the LED by

 void setup() { //this sets the output pins

 pinMode(11, OUTPUT);
 pinMode(10, OUTPUT);
 pinMode(9, OUTPUT);
 pinMode(8, OUTPUT);
 }

 void loop() {
 int ledcolor = random(1,16); //this randomly selects a number between 1 and 15

 switch (ledcolor) {

 case 1: //if ledcolor equals 1 then the led on pin 11 will turn on etc.
 analogWrite(11, brightness);
 brightness = brightness - fadeAmount;     break;
 case 2:
 digitalWrite(10, HIGH);
 delay(a);
 digitalWrite(10, LOW);
 break;
 case 3:
 digitalWrite(9, HIGH);
 delay(a);
 digitalWrite(9, LOW);
 break;

In order to fade in and fade out LEDs you need to use PWM feature. And, specifically you need to use the analogWrite() function call. Also, you need to make sure all your LEDs are connected to PWM port pins.  Port pins which support the PWM feature for various Arduinos are listed in the above link.

In your code you might try replacing your 500ms delay with a count up followed by a count down loop.  Each loop should contain the appropriate delay and count up or down to the appropriate value.

For instance, you might try a 1ms delay and a count from 0 to 255 followed by a count from 255 to 0.  In both loops just before or just after calling the delay() function, place the call to the analogWrite() function and pass the counter value as the PWM duty cycle (LED brightness setting).

added later...

For example, you might try to see if this code works for the 1st case statement:

int brightness_level;

case 1: //if ledcolor equals 1 then the led on pin 11 will turn on etc.
  for(brightness_level = 0 ; brightness_level < 255 ; brightness_level++)
  {
    analogWrite(11, brightness_level);
    delay(1);
  }
  for(brightness_level = 255 ; brightness_level >= 0 ; brightness_level--)
  {
    analogWrite(11, brightness_level);
    delay(1);
  }
break;


Arduino for Wi-Fi hotspot? I want to create a Wi-Fi hotspot and redirect all connections to a custom login page.

I would like to know if the Arduino Yún is a good choice in this case?

Better use a regular router and flash DD-WRT or OpenWRT to it (check the supported router list on their websites). Next use something like NoCatSplash, to create a captive portal with login.

Arduino's just are not fast enough for this. Arduino Yuns are typically more expensive.


Specify F_CPU in arduino to use 8MHz clock I am using a custom made AVR board with Atmege-328p on it and it doesn't have a 16MHz crystal on it. I would like to use the internal 8MHz as clock. I have set the appropriate Fuses but now I am unable to tell the programs that F_CPU is 8000000UL. One way of doing it is to add another variant to the boards. I would like to if there is another way to set F_CPU ?

No, the boards.txt file is where it is defined and the only place it is (or can be) defined. Making a new board variant is the proper way of adding a new board with new settings.


Arduino Uno - ESP 8266: sending AT commands via Code I bought a ESP 8266 & I am able to send AT commands and receive response via serial monitor when I upload a empty sketch. I changed the baud rate from 115200 to 9600 by using AT+CIOBAUD=9600 and am able to run AT commands at 9600 baud rate.

Empty Sketch:

void setup()
{

}
void loop()
{

}

Here is how my circuit looks:

Problem

The problem is when I create a custom sketch to run AT commands it doesn't work. Here is how my sketch looks:

#include <SoftwareSerial.h>
SoftwareSerial esp8266(0,1); //RX,TX

void setup()
{

  Serial.begin(9600);
  esp8266.begin(9600);

  Serial.println("Run AT Command");

   esp8266.print("AT\r\n");

}

void loop(){
   String response = "";
   while(esp8266.available())     {
        char c = esp8266.read();
        response+=c;
        Serial.print(c);
      }

      if(response != ""){
        Serial.println(response);
      }

}

ESP8266 is receiving 3.3V but I have read TX and RX sends 5V, and they also need to be 3.3V. Don't know if thats what is causing it, but I am able to run AT commands on empty sketch, so this is a bit weird.

  UPDATE:

My sketch is:

#include <SoftwareSerial.h>
SoftwareSerial esp8266(2, 3); //RX,TX

void setup()
{

  Serial.begin(9600);
  esp8266.begin(9600);

  esp8266.print("AT\r\n");

}

void loop() {
  String response = "";
  while (esp8266.available())     {
    char c = esp8266.read();
    response += c;
  }

    if (response != "") {
      Serial.println("Response: " + response);
    }

}

Serial Monitor shows this:

Response: A
Response: T

OK
Response:

OUTPUT when I run AT+CIFSR command:

Response: A
Response: T+CIFSR

Response:
+CIFSR:APIP
Response: ,"192.168.4.1
Response: "
+CIFSR:APMA
Response: C,"5e:cf:7f:80
Response: :f7:74"

OK

Question now is: How do I store the string being returned from the esp8266. I thought my response string was suppose to store the "OK" but that did not happen.

Of course you cannot use the same pins for both hardware and software serial, but that part seems to have been solved in comments.

  Question now is: How do I store the string being returned from the esp8266. I thought my response string was suppose to store the "OK" but that did not happen.

 while (esp8266.available())     {
    char c = esp8266.read();
    response += c;
 }

This will only read as long as characters are available, but the ATmega is able to run this loop much more quickly than characters are received, so unless the entire message was previously transferred it will likely only get a character or two before the receive buffer is found (temporarily) empty and it terminates.

You should instead read until a terminating condition is found, such as a newline character.  For safety you might also put in a "give up and try again" timeout, but make it long.

Some would try to solve this problem by inserting short delays before trying to read, but that is unwise - depending on delays creates unreliability as the necessary delay can easily change due to conditions that may on the surface seem to have little relevance, for example the esp866 might respond more slowly if it is seeing a lot of broadcast traffic on a network, or if the firmware version changes.


SDA/SCL pins Arduino Uno I am trying to figure if SDA and SCL pins from Arduino Uno is a TTL or a CMOS technology. I am not able to find this info anywhere but regarding it is a I2C protocol it does make sense to be a TTL technology. Can someone kindly confirm this info, please?

It is CMOS in that the IO pins of the MCU use MOSFETs not BJTs.

However I2C is slightly different in that it is open-drain not push-pull, so it's not really either TTL or CMOS since it doesn't conform to either logic level standard (since there is no "high" voltage, only what is pulled up by the external resistor). That said, since the ATMega is normally CMOS when in input or push-pull mode the logic levels of the I2C should conform to CMOS not TTL in order for the Arduino to read them properly.

It's closer to RTL than TTL or CMOS.


Who makes this cool Arduino display shield, and what model is it? Anyone recognize Mfgr/model of this display that reads: "Wireless Internet Of Things".  The Arduino board is a WIOT.

I've been looking and looking for a source for Arduino display like this, but cannot find.

That will be an SSD1306 based blue OLED display with SPI interface. There's lots of them around by lots of different people. Some are I2C interface, and some of those have a "broken" I2C interface that doesn't send ACKs (especially cheap ones on eBay) and need a special ACK-less Software I2C implementation.

The SPI ones, of course, won't suffer from that problem.

They are generally 0.96" diagonal, and that one, I think, is 96x39 pixels (or it may be 128x64).


Communication between Raspberry PI (Windows IOT) and Arduino with ESP8266 I'm currently working on a Home Automation project where I have a Raspberry Pi on Windows IoT which communicates with multiple arduinos running on FreeRTOS (I need multi-tasking).
At the moment the communication is through the serial port using Xbees, the Pi sends a command, and the arduino send's back a string in JSON format.

For cost optimisation reasons, I want to try to switch the Xbees with ESP8266 modules. Is it possible to get the same kind of serial communication over WIFI?Thanks.

Is it possible to get the same kind of serial communication over WIFI?

Not precisely, no - but TCP sockets are a similar concept.

You would be best programming the ESP8266 directly to implement a simple TCP to UART bridge firmware instead of fighting with the crummy AT firmware that comes with them.


Fan dropping voltage? I have students using an arduino to control a fan.  We have multiple types of fans. We want to turn the fan off/on with digital HIGH.  When the 5V fan is plugged into 5V and ground, it runs.  When I ground it and attached the power side to a pin set to HIGH the voltage drops down to 2.2V??? When the fan is not plugged into the pin there is 5V.  Why would the power drop when the fan is plugged in?

Most digital pins on Arduinos are qualified to handle up to 25 mA typically and 40 mA at most.  If more current than that is drawn or sunk, the pin voltage will drop or rise, out of specification.  This is due to resistance in the pin drivers, and by Ohm's law, voltage equal to current times resistance will develop.  That “lost” power (voltage times current) is converted to heat within the microcontroller, and can damage it.

The fan motors probably draw rather more than 25 mA; they probably require a few hundred mA.  You can add transistors or motor controllers between the Arduinos and the fans to deal with such current loads.


if/else statements without comparison operators and curly braces I recently came across this code in a tutorial. The code works, but this form of syntax seems to differ quite a bit from https://www.arduino.cc/reference/en/language/structure/control-structure/if/, as it's lacking comparison operators and curly braces for statements. Can someone please run down why this works?

for (int i = 0; i < 15; i++)
{
lcd.setCursor(i, 1);
if (pressed[i])
  lcd.print("X");
else
  lcd.print(" ");

if (justpressed[i])
  digitalWrite(led, HIGH);
else
  digitalWrite(led, LOW);
 }

About the missing conditions, e.g.:

if (pressed[i])

If is supposed to be a boolean, this is the prefered way, as long as the boolean has value zero (0) when false and nonzero when true. It is the same as writing:

if (pressed[i] != 0)

It is not usual to do this for integers, only for booleans.

About the brackets: If you have only one statement the brackets can be omitted. But it is quite a bad programming practice, since sooner or later you add a statement, without the brackets added and you have a bug introduced.

If you really want to shorten it than instead of

if (justpressed[i])
  digitalWrite(led, HIGH);
else
  digitalWrite(led, LOW);

use

digitalWrite(justpressed[i] ? HIGH : LOW);

This is called the Ternary operator.

update

Using the remark of wondra but with the ternary operation your code can be

for (int i = 0; i < 15; i++)
{
    lcd.setCursor(i, 1);
    lcd.print   (     pressed    [i] ? "X"  : " ");
    digitalWrite(led, justpressed[i] ? HIGH : LOW);
}


What's the problem with program , continously beeping buzzer I have used PIR motion sensor with arduino Uno r3, alongwith one piezo buzzer. and the program is as

 /*
 * PIR sensor tester
 */

int ledPin = 13;                // choose the pin for the LED
int inputPin = 2;               // choose the input pin (for PIR sensor)
int pirState = LOW;             // we start, assuming no motion detected
int val = 0;
int piezoPin = 11;
// variable for reading the pin status

void setup() {
  pinMode(ledPin, OUTPUT);      // declare LED as output
  pinMode(inputPin, INPUT);
  pinMode(piezoPin, OUTPUT);
  Serial.begin(9600);
  // declare sensor as input

}

void loop(){
  val = digitalRead(inputPin);  // read input value
  if (val == HIGH) {            // check if the input is HIGH
    digitalWrite(ledPin, HIGH);
    tone(piezoPin,300,160);
    delay(150);

    // turn LED ON
    if (pirState == LOW) {
      // we have just turned on

      // We only want to print on the output change, not state
      pirState = HIGH;
    }
  } else {
    digitalWrite(ledPin, LOW);
    tone(piezoPin,0,0);
    delay(300);

    // turn LED OFF
    if (pirState == HIGH){
      // we have just turned of

      // We only want to print on the output change, not state
      pirState = LOW;
    }
  }
}

but it supposed to ring buzzer at the time of pir motion sensor getting signal. But buzzer continuously ringing and at the time of pir sensor getting signal, it just ring louder. What is the problem in program``

noTone()

Description

Stops the generation of a square wave triggered by tone(). Has no effect if no tone is being generated.

NOTE: if you want to play different pitches on multiple pins, you need to call noTone() on one pin before calling tone() on the next pin.


Programming ATMega328p using VP812 programmer (for AVR/Atmel chips) I bootloaded an ATMega328p (the one that uses the basic Arduino bootloader). Then, I used the VP812 for dumping other programs written in C (in Atmel Studio).

The process of erasing, blank test, programming and verification are all working fine and it seems that the program is actually being flashed. However, when I insert the same chip (controller) back in the Arduino Uno board, the controller doesn't function as programmed. Also, I am not able to dump any other example sketches.

Does this mean that the chip is damaged?
Does using the bootloaded chip with VP812 cause such problems?

Also, I used the "Write Fuse" option with the standard fuse configuration (all marks checked) in the VP812 configuration dialog box. Did this setting in any way create the problems I am facing now?

Yes - the settings created this problem. You have erased and disabled (via default fuses) the bootloader. It means that your application will run perfectly fine on an Arduino board, but you will not be able to flash over USB.

If you want to use Arduino USB bootloader again then you have to follow this guide


How to turn the digital pin to analog pin? I am using a 10 IR sensor array and they use analog pins. I am using a motor shield for the Uno. So I cannot use the Mega. I have only five analog pins I need 8. How can I do it?

You can use an external A/D converter, there are a lot of varieties in a lot of price ranges for the Arduino. Check your favorite online source. That will require two of your existing analog pins for the I2C interface but you will gain back many more depending on your choice. If you choose to use SPI that will take 4 pins.


Circuit doesn't work when multimeter/current meter is attached I'm working on a battery-powered data logger, using a bare Atmega 328. I'm using sleep between sensor readings, via the Narcoleptic library. Everything seems to work fine, until I connect my multimeter to check on the current.

The multimeter uses manual range-setting (i.e., not autoranging). If I set the multimeter to the 0-20 mA range, I can see that my idle current is about 0.250 mA, but the upper value is off-scale. If I try to get a reading on the 0-200 mA range, the circuit misbehaves, never goes into sleep, and doesn't record any data. The current stays constant somewhere around 14-20mA.

Do I need to do something special to accurately measure current in the range of 0.25-40+mA? Or do I need a different kind/quality of multimeter?

My multimeter is a $15 digital unit from Circuit Test, model DMR-1100A.

Multimeters have something called a "burden voltage". See this PDF: uCurrent - A professional precision current ... - EEVblog.

Also see Dave Jones' video: µCurrent

Meters measure current by dropping voltage over an internal resistor, and measuring the drop. By definition therefore, there is a voltage drop, which is the "burden voltage".

  the circuit misbehaves, never goes into sleep, and doesn't record any data

If you put a voltmeter on the processor side of the ammeter you will probably find that the voltage going into your processor is somewhat less than you think. That would account for the misbehaving.

One possible approach is to crank up the voltage from your power source, checking the voltmeter to see that it reaches the expected voltage on the processor side of the ammeter, however in a circuit which might turn on and off (ie. sleep) this voltage might jump around (depending on the current) so this should be done with caution (to not exceed the maximum processor voltage).

  Or do I need a different kind/quality of multimeter?

A higher quality meter may well help - watch that video and look at the PDF to see what I am talking about. My meters (which cost more than $15) don't have this problem to the same extent.


Battery Status notifier I am new to Arduino, and I am aware that unlike Raspberry Pi you do not have a full blown OS with many custom applications running concurrently.
I plan to start an Arduino project with an Arduino NANO that will need to be portable, and include batteries. How may I get the battery status information without disrupting the rest of the functionality?

Use analogRead to measure the voltage on the battery. You might have to use the internal 1.1V reference to get a good reading.

Don't write any blocking code and the processes won't interfere with each other. That means no long for or while loops waiting for something to complete and absolutely no delay.


HTTP PUT method on NodeMCU/ESP8266 I've been trying to send a put request from my esp8266 for a while not but I can't figure out why it doesn't work and there are barely any posts about put requests online
I keep getting errors around int httpCode = http.sendRequest("PUT", String(data));

Error log: https://gist.github.com/dkbay/ab3fedf5e89d841d25b24fb829df74ef

#include <ESP8266HTTPClient.h>

#define LED_BUILTIN 2

const char* ssid     = "Some SSDI";
const char* password = "Some wifi password";

int wifiStatus;

void setup() {

  Serial.begin(115200);\
  pinMode(LED_BUILTIN, OUTPUT);
  delay(200);

  // We start by connecting to a WiFi network

  Serial.println();
  Serial.println();
  Serial.print("Your are connecting to;");
  Serial.println(ssid);

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    digitalWrite(LED_BUILTIN, LOW);
    delay(500);
    digitalWrite(LED_BUILTIN, HIGH);
    Serial.print(".");
  }

}

void loop() {
  wifiStatus = WiFi.status();

  if(wifiStatus == WL_CONNECTED){

    HTTPClient http;

    http.begin("http://google.com/");
    http.addHeader("Content-Type", "application/json");
    String data = "{\"on\":false}";
    int httpCode = http.sendRequest("PUT", String(data));
    String payload = http.getString();

    Serial.println(httpCode);
    Serial.println(payload);

    http.end();
     Serial.println("");
     Serial.println("Your ESP is connected!");
     Serial.println("Your IP address is: ");
     Serial.println(WiFi.localIP());
  }
  else{
    Serial.println("");
    Serial.println("WiFi not connected");
  }
  delay(1000); // check for connection every once a second

}

HTTPClient http;
http.begin("http://google.com?on=false");
http.addHeader("Content-Type", "application/json");
int httpCode = http.sendRequest("PUT", "");
String payload = http.getString();

try with this code, if server .php,
get data by $_REQUEST


How to send data from ThingSpeak to ESP-8266 (Arduino) using ThingHTTP? I have made an Arduino kit that acts as a weather station. It sends sensors data (DHT11 & LDR) to the ThingSpeak web server.

Now I want to perform some actions based on the data on the ThingSpeak server (like if temperature exceeds a limit turn on the fan, etc).

I've searched and I found that there's a React app on ThingSpeak, which will trigger events if data exceeds some values.

The problem where I got stuck is that I want to send a signal from the ThingSpeak web server to my ESP8266 (Arduino) to turn on/off the device connected to a relay on Arduino.

I've figured out that there's also a ThingHTTP feature which sends HTTP requests. But I don't know how to send requests/signals to my kit to perform some actions.

I've already spent 2 months building this project, and now I'm stuck in the last part. Please give your valuable suggestions and solutions.

For sending information to/from Arduino best option is MQTT. It's lightweight and very simple to use.

While your Arduinos are using MQTT to send info and receive commands (like changing thresholds), your Web server has access to the same information in real time. You can format it and present it in any way you like, without any Arduino participation.


Unable to issue any AT commands to BT BLE Breakout Board I'm a programmer, more from the software side but I do have hardware working knowledge too. I've completed the Arduino Starter Kit's 15 projects, Now trying to build some things with ESP8266 and HM-10 BLE.

I was able to connect ESP8266 to my network and start a TCP server too via AT commands(using  Arduino's Serial Monitor and FTDI 232RL USB to TTL converter)

I also have a HM-10 Bluetooth Breakout+connector board (Its based on CC2541 by TI (visible on the SMD chip)) brought from here.

Using the same setup I was able to issue AT commands successfully for ESP8266. However I tried many things, different baud rates and \r\n combinations; I just couldnt get the HM-10 to acknowledge my AT commands.

Setup: link

Connections:

Arduino +5V --> +ve input of LDO regulator --> 3.3v OUPUT to Vcc of HM-10
Common GND for LDO regulator input and output pins, FTDI 232RL and HM10

FTDI TX --> voltage divider (1k ohms --> connection output to HM 10 RX --> 1k ohms --> 1k ohms --> GND)

There is no code/sketch as of now. I'm just trying to hook up the HM-10 BLE chip. I can pair my Android phone to it but that's not the concern here.

The concern here is I cannot configure the HM-10 using AT commands.

The HM-10 does not reply an "OK" acknowledge for my "AT" command. Nothing happens in the serial monitor after hitting enter. Just a blank screen.

Is there a way by which I can determine what baud rate to use and what combination of \r and \n?

What am I missing here?

I found out that there is no need for a voltage divider to reduce the voltage being given to RX pin of BLE from FTDI's TX since both FTDI232RL and HM-10 are 3.3V devices (from here)

I connected the TX from FTDI directly to the RX of BLE using female to female jumpers.

Used No Line Ending and 9600 as the baud rate.

Then it worked fine, I got an OK acknowledge for my AT command.


Variable Fan Controller - Properly Sized Transistor I would like to a build a temperature sensing variable speed fan controller for my truck. Currently using a purchased 2 speed on/off relay based controller, but my fans are overloading the whole circuit when the controller is powered on during a high speed temperature scenario. On low speed, I have the fans wired in series to spin both slower - works great. Each fan initially draws 100 amps at full 12v. On the low speed (6v/series), they cruise about 20a together. On high speed, they settle in around 25a each.
I am somewhat experienced with arduino and using a few references to build in specific features I want, but here is the main example I am going by.
https://circuitdigest.com/microcontroller-projects/automatic-temperature-controlled-fan-project
My question is around the type and size of transistor that I would need to handle the amount of current these fans draw. Some examples have MOSFET while others have FET or even standard PNP. I am pretty new to working with transistors and can't find any references that make sense. Would love to get a reference to learn this calculation and appropriate type.
Edit: removed picture with incorrect wiring diagram.

Doing a quick search for high-current MOSFET transistors, I ran across the following:
https://www.digikey.com/en/products/detail/ixys/IXFK170N20T/2126313
The important spec here is the Rds ON (max) of 11mOhm @ 60A, 10V
At your peak current of 100A, you would drop 1.1V across the transistor, for a power dissipation of 110W.
The advertised P(max) is 1150W, so assuming the junction temp can be held to under 175C (and with an entire metal truck to use for a heat sink, this shouldn't be a problem) you should be OK with this device.  In the 'cruise' configuration with 25A motor current, you should have no problem controlling the fans.
YMMV ;-)


Source power with 2 V and LED with forward voltage of 2 V I have a source power with 2 V and 100mA. I have an LED that has a forward voltage of 2 V and a max current of 20mA.

Should I use a resistor to reduce the current? I see many formulas in the internet saying the the resistor value should be:

(Source Voltage - LED forwared voltage)/LED max current

This formula always worked fine for me, but now that I have a 2 V source power this formula tells me that the resistor should be 0 ohm. Of course this would damage my LED cause the 100mA provided by my source power is way above the 20mA current limit of the lED.

No, it would not damage your led. The forward voltage of a led is, the voltage at which the led 'conducts' the maximum current it can handle. Since diodes have a (exponential) curve, the current though a diode depends on the voltage across it.

So if you give the led 2V, it will use only 20mA. However if the voltage goes to e.g. 2.1V the current might be 25mA (since the curve is exponential), which is a bit too high, and will reduce the leds lifespan.

So for safely I'd add some resistors. E.g. a 10Ohm resistor will limit the current to 20mA max, as long as the voltage doesn't go over 2.2V

PS note that led Christmas lights use the same method to limit current, without a single resistor. I have here a 24v string of leds, grouped into 10 leds connected in series. So the voltage across each led is 2.4V. They are white leds, so they probably have a forward voltage of around 3.2v. But since they only get 2.4v, they will probably use only 5mA or less.


Arduino Strings concatenation I am working on an arduino mega 2560 sketch.
I have to parse http query strings.

My program is concatenating strings for each http request.
And i have an http request every second during all day.

I have read that this kind of work may cause ram memory fragmentation. I am very upset about this because my program will randomly crash if there are no free ram memory.

Do you know if there is a way to initialise a string with a given memory length ?

I do not want to work with char arrays because i need indexof, substring functions and comparison with ==

Thanks

There is a way to initialize an Arduino String with a given memory length: see reserve() method. It will generally greatly reduce or entirely eliminate memory fragmentation, if you can afford reserving a sufficient amount of memory in advance.

Just keep in mind that this is a "soft" boundary: once your string gets longer than the reserved amount, String will quietly resume reallocating memory with all those typical consequences.

It is not clear what you plan to do if the pre-reserved amount of memory proves to be insufficient. Fall back to "memory fragmentation"? Anything more elaborate than that will be pretty much as complex as performing manual management of a char[] array.

All the functionalities you requested are present for char[] arrays as well, might just require a few more lines of code. And it is not clear why one might "need" comparisons to be == specifically.

This might also be an XY problem. Why are you trying to concatenate all these requests in memory? What are you planning to do with them once you are done "concatenating"?


How do I control 4 LEDs with 2 Digital Outputs? In an effort to learn about transistors that seemed easy enough. But I can't get it to work in practice

Can I control 4 LEDs with just 2 digital outputs (High, Low). So I figured I would use the difference between PNP and NPN transistors to create logic gates.

[00,01,10,11]

But I can not seem to get this to work in practice for the life of me.

I read about Charliplexing, but that is n*(n-1), which isn't good enough. I've also read about shift registers, but I'm not sure I fully understand (I'm a noob), and it sounds like you need a minimum of 3 pins. Is what I am trying to do even possible? If not, then why?

Using two pins it is possible to drive 4 LEDs as long as you only want one of them on at a time.  One LED will always be on - it's not possible to have a setting where there is no output selected.

Basically you are "decoding" a binary value output:

00 = LED 1 on, other three off
01 = LED 2 on, other three off
10 = LED 3 on, other three off
11 = LED 4 on, other three off

To do that you need to use (or construct) a 2-to-4 decoder.

Using logic gates it can be constructed like this:

If you can translate that into transistors then you'll end up with quite a lot of transistors.  Most people would use a specific 2-to-4 decoder chip such as the 74HC139.

Shift registers usually require three pins, yes, though there are possible ways of working with two pins.  You require two pins to provide the data and clock signals, and a third pin to latch the shifted data out to the outputs. However it is possible to use the first leading edge of the clock signal or a specially formatted data signal with a capacitor to create a pulse just before sending new data which can latch the old data.  This requires careful consideration though regarding how fast you would be transmitting, etc, and is not really recommended.

A better solution if you are limited in pins and need to drive multiple LEDs is to use WS2812 "NeoPixel" LEDs which chain together and use a single wire protocol to send data to all the LEDs in the chain.  You can support many LEDs (even hundreds) on a single IO pin, and they are full 24-bit RGB to boot.


Unable to read the IC Card UID I have a RFID module using NXP RC522 chipset.

I have no idea that is it correct the module using 27.120 mHz

And I have 4 IC card,

A) 0005302176, (Blue color tag, come with the RFID module)
B) 0008846830 134,65006 (White card, come with the RFID module)
C) 0004189112 063,60344 (White card)
D) White card, no number print on the card. Only this card UID can be read.

Here is the pinout

Which I connected to Arduino UNO R3

     RFID         UNO R3
(Pin Name, Pin)    (Pin)
SDA        1        10
SCK        2        13
MOSI       3        11
MISO       4        12
IRQ        5        -No Connect-
GND        6        Ground
RST        7        9
3.3V       8        3.3V

PS: I am using this library, and this example.

PS: The serial return this information MFRC522 Software Version: 0x91 = v1.0

Check your power source, if you are powering the module from arduino/USB=>part or something like that, there can be not much power for the module.
Also you can try powering it 5v (not 3,3 as they should be powered by reference).

In my case I have had problems reading some types of cards, and I have solved that problems by giving better power supply, also higher power supply than in reference for some of the cards.

"By magic" the cards that were not working started working as a charm.

Also you should check if the cards you are using are all  ISO14443 A

Only that kind of cards is compatible with that reader.
So if you got type B, or other type of ISO cards, that will not be working.
Some of them may use different frequency, there is a bunch of standards around.

Also as said before the cards can be damaged, or could be corrupted if you tried reading UID while writing to the card, the problem is known , and in that case you can damage the UID.

I hope it helps you.
cheers


Charge lipo battery while using I have a system that uses Arduino and some modules. The system needs 5v dc power with 3A current at maximum(The system needs 3A current for some seconds every 5 minutes and after that the current will get back to 300-400mA) and on the other side i have a 5v dc charger with 400-500 mA current. So my problem is lack of amperage and i can't run correctly Arduino with 5v dc charger. For solving this problem i want to use a Lipo battery to connect to Arduino but the battery will ran out and i can't get energy from battery so i want to connect the battery to my charger while the Arduino uses the battery, How can i do that? Is there any module to do this work? Can i use TP4056 with protection version to do this work?(Note: I can't change charger)

You really shouldn't charge a lithium battery whilst discharging it. The charger may either never know that it has finished charging and overcharge it, or shut off early and never charge it up properly at all.

Instead you should arrange that your MCU is powered directly from the PSU so that it always has stable power, and feed that same power into a normal charger via some form of electronic switch so it can be turned on and off. The output of the battery can then be fed through another switch into your heavy load.

When it comes time for your load to be activated you switch off the power from the charger and switch on the connection from the battery to the load.

What you use to do the switching is entirely up to you - whether you choose P-channel MOSFETs or relays entirely depends on your situation.

Here's a block diagram to better illustrate it to you:

simulate this circuit – Schematic created using CircuitLab


Combining codes for 3 sensors I am trying to combine codes for my 3 sensors: GSR, Pulse sensor, and ECG but I keep getting errors. I have a poor background in coding. I have the 3 codes separately and I'm not the one who wrote them.
Here are the new Sketch after Combining the loops and the setups.I didn't get any error after uploading and verifying but I am not getting values in my Serial Monitor

Combined sketch:

<!-- language-all: lang-cpp -->

#include <Wire.h>
#include "rgb_lcd.h"
#define ANALOG_IN 2   // analog input pin to display
#define OUTPUT_PIN 10 // test signal output pin
#define PULSE_MS 250  // pulse width in ms

int PulseSensorPurplePin = 1;        // Pulse Sensor PURPLE WIRE connected to ANALOG PIN 0
int LED13 = 13;   //  The on-board Arduion LED
int Signal;                // holds the incoming raw data. Signal value can range from 0-1024
int Threshold = 550;            // Determine which Signal to "count as a beat", and which to ingore.

const int BUZZER=3;
    const int GSR=A0;
    int threshold=0;
    int sensorValue;
    rgb_lcd lcd;

long ms;        // timer in ms
int out = HIGH;     // output level

void setup() {
   pinMode(LED13,OUTPUT);         // pin that will blink to your heartbeat!
   Serial.begin(9600);         // Set's up Serial Communication at certain speed.

   long sum=0;
      //VERIFY VALUE
      lcd.begin(16, 2);
      Serial.begin(9600);
      pinMode(BUZZER,OUTPUT);
      digitalWrite(BUZZER,LOW);
      delay(1000);
//VERIFY VALUE
      for(int i=0;i<500;i++)
      {
      sensorValue=analogRead(GSR);
      sum += sensorValue;
      delay(5);
      }
      threshold = sum/500;
       Serial.print("threshold =");
       Serial.println(threshold);

       pinMode(OUTPUT_PIN, OUTPUT);    // set output pin mode
       Serial.begin(19200);        // initiate serial communication
       digitalWrite(OUTPUT_PIN, out);  // set initial digital output
       ms = millis();          // query current time (in ms)

}

void loop() {
  Signal = analogRead(PulseSensorPurplePin);  // Read the PulseSensor's value.
                                              // Assign this value to the "Signal" variable.

   Serial.println(Signal);                    // Send the Signal value to Serial Plotter.

   if(Signal > Threshold){                          // If the signal is above "550", then "turn-on" Arduino's on-Board LED.
     digitalWrite(LED13,HIGH);
   } else {
     digitalWrite(LED13,LOW);                //  Else, the sigal must be below "550", so "turn-off" this LED.
   }

delay(100);

   int temp;
      sensorValue=analogRead(GSR);
      Serial.print("sensorValue=");
      Serial.println(sensorValue);
      lcd.setCursor(0, 0);
      lcd.print("GSR Value: ");
      lcd.print(sensorValue);
      temp = threshold - sensorValue;
      if(abs(temp)>50)
      {
        sensorValue=analogRead(GSR);
        temp = threshold - sensorValue;
        if(abs(temp)>50){
       digitalWrite(BUZZER,HIGH);
        Serial.println("YES!");
        delay(3000);
        digitalWrite(BUZZER,LOW);
        delay(1000);}
      }

      int val = analogRead(ANALOG_IN);    // read voltage at input pin
  Serial.write( 0xff );         // write value to serial port
  Serial.write( (val >> 8) & 0xff );
  Serial.write( val & 0xff );

  if (millis() >= ms+PULSE_MS) {    // check if pulse width has elapsed
    ms = millis();            // query current time (in ms)
    out = !out;             // invert output value
    digitalWrite(OUTPUT_PIN, out);    // update digital output
  }
}

In general:

There can be only one setup, in most cases you can put the code from all three setup's together, but checkout the code does not interfere, i.e. does not use the same pins. In that case, change the pin numbers if possible (and change the circuit accordingly).
For the loops it can be more tricky:

Check how often each loop should be called. If one loop costs e.g. 500 ms that means the other loops will be called less often, which can affect the precision or even good readout of the sensor.
If all loops are relatively small and the duration do not matter, you can just call them after each other (rename the loops and call them one by one).
If there is a time constraint, than split the lengthy loop in a small part, and call it whenever needed. There is no clear rule for this.

What you can try is:

Check for reach loop how long it takes
Than for each loop add a delay with same time as the other loops, thus:

Test the duration (average) of loop 1, than of loop 2, than of loop 3. Assume loop1 takes 100, loop2 200 and loop3 300 ms.
Test loop1 without calling loop2 and loop3, but just add the delay (200+300=500 ms).
Check if it works, if so, it means you can call the other loops without problems.
Do the same for loop2 (with 100+300ms delay) and loop3 (100+200ms).
If all loops work correctly, than you can call the loop1, loop2, loop3 in sequence.
If not, you have to call the loop(s) that do not work either more often or in a different way.


Confusion over Transistors for a switching circuit with an Arduino Mega 2560 Apologies if this is a stupid question asked by a noob, but I've looked around to try and find the answer and just can't work it out.

Basically, I'm making a project on thingiverse (Glitch's MK2 Stargate), and I've tried all sorts of different transistors with my circuit, I just can't get it to work properly.
Could you please advise which Transistor would work for the following circuit:

It's a basic thing, but the plan I was originally working from on thingiverse called for BC548BU transistors, however, the LEDs they were using were surface mount, and I am trying the same thing with 3mm standard LEDs. The BC548BU didn't work right on the normal LEDs.

I'm a total noob with this, but I've been trying to match the Base pin on the Transistor voltage output of my Arduino, but not sure if I'm doing the right thing. Can anybody help?

Thanks
-Dave

p.s. I have a load of transistors already (listed below), if any of these work, that would be great, if not, I will order the correct ones. The only one that seemed to match Data with the BC548 is the S9014, but it didn't seem to work at all, unless my understanding of the wiring of Transistors needs adjustment.

A transistor amplifies current, not voltage.

The first thing to check is the current of your LEDs. In your current configuration, it is between 25 and 30 mA. This is too high for most LEDs. Check the datasheet of your LEDs for the actual forward voltage, and current rating.
To calculate the value for the resistor in your circuit, use Kirchhoff's and Ohm's laws. According to Kirchhoff: VResistor + 3 VLED = 12 V. Let's assume that the LED's forward voltage drop VLED = 1.8 V. This means that VResistor = 12 V - 3 VLED = 6.6 V. Ohm's law will then tell you the relationship between the voltage across the resistor and the current through it: R = VResistor / I. The current through the resistor is the same as the current through the LEDs. Let's assume that this is 20 mA. Therefore: R = VResistor / I = 6.6 V / 0.020 A = 330 Ω.

The next thing to calculate is the resistor between the Arduino and the base of the transistor. As mentioned before: the voltage on the base does not matter, the current does. You want to use the transistor as a switch, so you have to drive it into saturation. As a general rule of thumb, you want the base current to be a tenth of the collector current in that case: IBase = ICollector / 10. The current through the collector is the same as the current through the LEDs, so IBase = 20 mA / 10 = 2 mA.

In a similar way as before, we can calculate the base resistor: VResistor + VBase-Emitter = VArduino. The voltage of the Arduino pin is most likely 5 V, and the Base-Emitter voltage of a silicon transistor is around 700 mV (look it up in the datasheet): VResistor = 5 V - 0.7 V = 4.3 V. Then use Ohm's law again to calculate the resistor value: RBase = VResistor / IBase = 4.3 V / 0.002 A = 2150 Ω ≈ 2.2 kΩ.

The current has to flow through the base to the emitter. For current to flow, you need at least two connections: current flows from the Arduino pin, through the transistor, to ground. You have to connect the emitter of the transistor to the Arduino's ground.

You can use pretty much any normal transistor that has a maximum collector current that is larger than the LED current, and a maximum collector-emitter voltage greater than your power supply.


Why does getting list of files from SD card FAIL if not printing to Serial? (ESP8266) I've got this piece of code for reading a list of files from root directory on SD card, which I run on ESP8266 chip (maybe it makes a difference):

  File dir = SD.open("/", O_RDONLY);

  int n = 0;
  while(true)
  {
     File entry =  dir.openNextFile();
     if (!entry) break;
     if (!entry.isDirectory())
     {
       Serial.println(entry.name());
       Serial.flush();
       n++;
     }
     entry.close();
  }
  dir.close();
  Serial.println(n);

The code works fine, but can someone please tell me why, when I comment out printing file names to the Serial in this loop, the program crashes? How is this possible? Are the files opened too rapidly or what? And how can I get the list, let's say into a vector<String> without printing it to the Serial?

When I comment out the printing the chip crashes with this in output:

ctx: cont
sp: 3ffeb540 end: 3ffeb950 offset: 01b0

>>>stack>>>
3ffeb6f0:  000000ff 00007c52 0000012c 3ffea30c
3ffeb700:  000000c0 3ffea4dc 00000000 40203a70
3ffeb710:  00000040 000000ff 3ffea318 402042f7
(...)
3ffeb940:  00000000 00000000 3ffea930 40100378
<<<stack<<<
ň"_Çc_ÇĎ

Try to use "delay(0);" in the loop (or yield() maybe).