RFID access system with PN532 reader I have a PN532, so it's capable of both reading and writing. I've used it for a few perfectly functional things, but I want it to authenticate based on the contents (for example 1024 bytes) of a tag.

I'd generate some pseudorandom data, possibly on my PC, and write that into each card, and use a checksum of that as the key.

Should I just stick with the standard authentication of tokens, or is this a worthwhile alternative method? The UIDs of the tokens are not interesting for authentication.

If worthwhile, what checksumming algorithms should I use? If not, would someone care to explain how I can program the memory of tokens, and how to use that in addition to UID for auth?

Thanks in advance.

First off, you don't want to use a checksum for authentication.

A checksum can be thought of as a hash with a very small size. The smaller the size of a hash the less unique it is. The less unique it is the more likely it is that incorrect data will generate the same hash and authenticate someone it shouldn't.

For instance, a 32 bit checksum (hash) of 1kB data (8192 bits of information) is a 256-fold reduction in the uniqueness of the value. At 32 bits you get 232 unique values. With 8192 bits you get 28192 possible values. I can't calculate how many values that actually is, but as you can imagine there will be many billions of billions of combinations that would all equate to the same checksum.

If you must use a checksum then make it an actual recognised hash. For instance an MD5 (considered weak by today's standards) has 128 bits. SHA-256 has, as you would imagine, 256 bits.

However calculating these hashes on an Arduino is not a simple matter owing to a lack of memory. Not impossible, but not that easy.

If you're going as far as to use such large amounts of data for authentication and using heavy mathematical routines to create a hash you may as well go the whole hog and use a proper cryptographic key pair.

One method would be to encrypt the UUID of the card off-line and store the encrypted result on the card - that data would then be unique to that card and tied to it - you wouldn't be able to clone the card unless you could clone the UUID as well.

Then either the UUID is read by the Arduino and also encrypted using the same key and if the results match authentication succeeds. Or the encrypted value is decrypted by the Arduino and compared to the UUID to see if they match. Which you choose depends on if you have asymmetric or symmetric encryption (the former is more like a hash but requires the encryption key to replicate it whereas a hash doesn't).

You can also include other information with the UUID, such as the name of the card owner (for identification purposes), etc - as long as you are able to already know that data to create the cryptographic has to compare with what is on the card.


Adafruit_GFX setRotation not working when called from within a class Using an ILI9341. I'm trying to set the rotation from within a class, but it's not working.  The code is very straight forward.

If I rotate in the class, the setRotation code does not work but the text is still printed. The pointer is set properly and the text is still printed, it just doesn't get rotated.

Outside of the class, the rotation works fine.

Any help would be greatly appreciated!

#include "SPI.h"
#include "Adafruit_GFX.h"
#include "Adafruit_ILI9341.h"

#define TFT_DC 5
#define TFT_CS 3

Adafruit_ILI9341 *tft;
uint8_t newRotationAngle = 0;

void drawStuff() {
    tft->setTextColor(map(rand(), 0, RAND_MAX, 0, 0xffff));
    tft->fillRect(0, 0, tft->width(), tft->height(), ILI9341_BLACK);
    tft->setCursor(0, 0);

    tft->print(F("01234567890"));
    delay(250);
}

class test {
public:
    void init(Adafruit_GFX *_p) { ptrTft = _p; };

    void inClassRotation(int newRotation) {
        ptrTft->setRotation(newRotation);
        drawStuffInClass();
    };

    void drawStuffInClass() {
        ptrTft->setTextColor(map(rand(), 0, RAND_MAX, 0, 0xffff));
        ptrTft->fillRect(0, 0, ptrTft->width(), ptrTft->height(), ILI9341_BLACK);
        ptrTft->setCursor(0, 0);

        ptrTft->print(F("01234567890"));
        delay(250);
    }

    Adafruit_GFX *ptrTft;
};

test instance;

void setup() {
    tft = new Adafruit_ILI9341(TFT_CS, TFT_DC);

    tft->begin();
    tft->setTextSize(2);

    instance.init(tft);
}

void outsideClassRotation(Adafruit_GFX *passed) {
    passed->setRotation(newRotationAngle);
    drawStuff();
}

void loop(void) {
    newRotationAngle++;

    // This works. No problems.
//    outsideClassRotation(tft);

    // This does NOT rotate but still prints the text fine.
    instance.inClassRotation(newRotationAngle);

}

I would actually be quite surprised if outsideClassRotation() actually
worked. My guess is that it does not work as is. Maybe it did work at
some point, but then you made some subtle changes to your code and did
not check that it is still working.

Here is the deal: there are two setRotation() methods:

Adafruit_GFX::setRotation(unsigned char) does very little besides
storing the rotation angle... which is not used anyway.
Adafruit_ILI9341::setRotation(unsigned char) actually sends commands
to the LCD asking it to apply the rotation; this is the method you
want.

The problem is that these methods are not virtual, which means that
when you call them through a pointer, as in
some_pointer->setRotation(the_angle);, you get the method
corresponding to the type of the pointer, not the type of the actual
object. For example:

tft->setRotation(the_angle);     // calls Adafruit_ILI9341::setRotation()
ptrTft->setRotation(the_angle);  // calls Adafruit_GFX::setRotation()
passed->setRotation(the_angle);  // calls Adafruit_GFX::setRotation()

I checked this by uncommenting your call to outsideClassRotation() and
disassembling the compiled binary: both times you are calling
Adafruit_GFX::setRotation().

Solution: change your Adafruit_GFX * pointers to be of
type Adafruit_ILI9341 *, or patch Adafruit_GFX.h to make
setRotation() virtual.


Get Speed Using GPS Neo with TinyGPS++ I am trying to get the current speed of my car using the GPS Neo, but my code always returns that the speed from the GPS is invalid. The green led of the GPS Neo is blinking. What is the isValid() function? Below the code:

#include <EEPROM.h>
#include <TinyGPS++.h>
#include <SoftwareSerial.h>
//LOAD WIRE LIB
#include<Wire.h>
static const int RXPin = 10, TXPin = 9;
static const uint32_t GPSBaud = 9600;
// The TinyGPS++ object
TinyGPSPlus gps;
// The serial connection to the GPS device
SoftwareSerial ss(RXPin, TXPin);
//***************************************************************
int aux = 0;
int vel_prog = 20; //programed SPEED
float vel_atual;//  actual SPEED
int val_inc = 0;
int val_dec = 0;
int led0 = 2;//led pin
int led20 = 3;//led pin
int led60 = 4;//led pin
int led80 = 5;//led pin
int ledsinal = 6;//led pin
int buzzer = 7;//buzzer pin
int incrementa = 8;//button pin
//****************************************************************
void setup()
{
  Serial.begin(115200);
  ss.begin(GPSBaud);
  pinMode(incrementa, INPUT);
  pinMode(led0, OUTPUT);  // declare LED as output
  pinMode(led20, OUTPUT);  // declare LED as output
  pinMode(led60, OUTPUT);  // declare LED as output
  pinMode(led80, OUTPUT);  // declare LED as output
  pinMode(ledsinal, OUTPUT);  // declare LED as output
  pinMode(buzzer, OUTPUT);  // dbuzeer
  delay(10);
}

void loop()
{

  smartDelay(1000);
  val_inc = digitalRead(incrementa);  // read increment button
  if (val_inc == 1) {
   if (vel_prog > 80) {
      vel_prog = -20;
   }
      vel_prog = vel_prog + 20;
  }

  if (vel_prog == 0) {
    digitalWrite(led0,HIGH);
    digitalWrite(led20,LOW);
    digitalWrite(led60,LOW);
    digitalWrite(led80,LOW);
  } else if (vel_prog == 20) {
    digitalWrite(led0,LOW);
    digitalWrite(led20,HIGH);
    digitalWrite(led60,LOW);
    digitalWrite(led80,LOW);
  } else if (vel_prog == 60) {
    digitalWrite(led0,LOW);
    digitalWrite(led20,LOW);
    digitalWrite(led60,HIGH);
    digitalWrite(led80,LOW);
  } else if (vel_prog == 80) {
    digitalWrite(led0,LOW);
    digitalWrite(led20,LOW);
    digitalWrite(led60,LOW);
    digitalWrite(led80,HIGH);
  }

  if (gps.speed.isValid()){
  Serial.print(gps.speed.kmph());
  } else {
  Serial.print("*");
  }

 if (gps.speed.isValid()) {
  if (gps.speed.kmph() >= vel_prog && aux == 0) { //comparacao da velocidades
    digitalWrite(ledsinal, HIGH);  // turn LED OFF
    tone(buzzer, 2200);
    delay(5000);
    digitalWrite(ledsinal, LOW);  // turn LED OFF
    noTone(buzzer);
    aux = 1;
  }
}
}

static void smartDelay(unsigned long ms)
{
  unsigned long start = millis();
  do
  {
    while (ss.available())
      gps.encode(ss.read());
  } while (millis() - start < ms);
}

These lines of code will wreak havoc with reading the GPS data:

tone(buzzer, 2200);
delay(5000);
digitalWrite(ledsinal, LOW);  // turn LED OFF
noTone(buzzer);

The Arduino is "blocked" at these lines for seconds.  During that time, the GPS keeps babbling and eventually overflows the input buffer.  The next call to smartDelay only waits for 1 second, and it may not get a complete sentence.

Here is a NeoGPS version of your sketch that does not block:

#include <EEPROM.h>
#include <NMEAGPS.h>
#include <NeoSWSerial.h>
#include <Wire.h>

NMEAGPS gps;

static const int RXPin = 10, TXPin = 9;
static const uint32_t GPSBaud = 9600;
NeoSWSerial gpsPort(RXPin, TXPin);

//***************************************************************
int aux = 0;
int vel_prog = 20; //programed SPEED
float vel_atual;//  actual SPEED
int val_inc = 0;
int val_dec = 0;
int led0 = 2;//led pin
int led20 = 3;//led pin
int led60 = 4;//led pin
int led80 = 5;//led pin
int ledsinal = 6;//led pin
int buzzer = 7;//buzzer pin
bool buzzing = false;
uint32_t buzzTime;
int incrementa = 8;//button pin
//****************************************************************
void setup()
{
  Serial.begin(115200);
  gpsPort.begin(GPSBaud);
  pinMode(incrementa, INPUT);
  pinMode(led0, OUTPUT);  // declare LED as output
  pinMode(led20, OUTPUT);  // declare LED as output
  pinMode(led60, OUTPUT);  // declare LED as output
  pinMode(led80, OUTPUT);  // declare LED as output
  pinMode(ledsinal, OUTPUT);  // declare LED as output
  pinMode(buzzer, OUTPUT);  // dbuzeer
  delay(10);
}

void loop()
{
  // Check the buttons
  val_inc = digitalRead(incrementa);  // read increment button
  if (val_inc == 1) {
   if (vel_prog > 80) {
      vel_prog = -20;
   }
      vel_prog = vel_prog + 20;
  }

  if (vel_prog == 0) {
    digitalWrite(led0,HIGH);
    digitalWrite(led20,LOW);
    digitalWrite(led60,LOW);
    digitalWrite(led80,LOW);
  } else if (vel_prog == 20) {
    digitalWrite(led0,LOW);
    digitalWrite(led20,HIGH);
    digitalWrite(led60,LOW);
    digitalWrite(led80,LOW);
  } else if (vel_prog == 60) {
    digitalWrite(led0,LOW);
    digitalWrite(led20,LOW);
    digitalWrite(led60,HIGH);
    digitalWrite(led80,LOW);
  } else if (vel_prog == 80) {
    digitalWrite(led0,LOW);
    digitalWrite(led20,LOW);
    digitalWrite(led60,LOW);
    digitalWrite(led80,HIGH);
  }

  // Check the GPS
  while (gps.available( gpsPort )) {
    gps_fix fix = gps.read();

    if (fix.valid.speed) {

      if ((fix.speed_kph() >= vel_prog) && (aux == 0)) { //comparacao da velocidades
        digitalWrite(ledsinal, HIGH);  // turn LED OFF
        tone(buzzer, 2200);
        aux = 1;
        buzzing = true;
        buzzTime = millis();
      }

      Serial.print( fix.speed_kph() );
    } else {
      Serial.print( '*' );
    }
  }

  // Check the buzzer
  if (buzzing && (millis() - buzzTime > 5000)) {
    digitalWrite(ledsinal, LOW);  // turn LED OFF
    noTone(buzzer);
    aux = 0; // Need this?
    buzzing = false;
  }
}

Notice how it checks millis() every time through loop to see if the buzzer has been on for 5 seconds.  It doesn't block for 5 seconds.

It only checks the speed when a new GPS fix arrives.  This happens once per second, not every time through loop.

Your original version uses 11472 bytes of program space and 786 bytes of RAM.
The NeoGPS version uses 10722 bytes of program space and 590 bytes of RAM, a significant savings.

NeoGPS is smaller, faster and more accurate than all other libraries.  If you want to try it, NeoGPS is available from the Arduino IDE Library Manager, under the menu Sketch -> Include Library -> Manage Libraries.

The above sketch also uses my NeoSWSerial.  It is much more efficient than SoftwareSerial.  SoftwareSerial blocks interrupts for long periods of time, which can interfere with other parts of your sketch.

It would be even better to use AltSoftSerial on pins 8 & 9 (on an UNO).


Error opening serial port '/dev/cu.Bluetooth-Modem'. (Port busy) I’m sorry if I sound ignorant and naive, but I’m brand new to Arduino;  very keen, but know very little.

I started with a Sainsmart Arduino Uno clone board.  I downloaded the software, which opened OK (or at least seemed to), but the Serial Monitor kept telling me that there was a communication error, and a yellow light kept flashing on the Sainsmart board.

I got hold of a genuine Arduino (from Jameco), uninstalled everything Arduino, and started again from scratch.

Now I get the message:

Arduino: 1.6.5 (Mac OS X), Board: "Arduino/Genuino Uno"
Error opening serial port '/dev/cu.Bluetooth-Modem'. (Port busy)
  This report would have more information with
  "Show verbose output during compilation"
  enabled in File > Preferences.

And after enabling the verbose output, got:

Arduino: 1.6.5 (Mac OS X), Board: "Arduino/Genuino Uno"
Error opening serial port '/dev/cu.Bluetooth-Modem'. (Port busy)

Tried again, and:

Arduino: 1.6.5 (Mac OS X), Board: "Arduino/Genuino Uno"
Error opening serial port '/dev/cu.Bluetooth-Modem'. (Port busy)

I’m using a MacBook Pro, using Yosemite 10.10.5.

You are not selecting the correct port to upload to - hence the strange message about the Bluetooth modem. Start by unplugging your Uno and running Arduino. Select Tools -> Port from the menu bar. You should see a list of options. Now plug in your Uno and do the same again. You should see an extra port listed now - this will be the Uno. Select it. You will need to check this every time you connect a board.

Also, before you click Upload, make sure you have Arduino Uno selected under Tools -> Board in the menu bar.


ESP8266 Arduino and Rotary Encoder I'm trying to use the sketch bellow to work with my WeMos D1 mini (ESP8266 Arduino platform) together with Rotary Encoder KY-040 or MJKDZ, and it's not working for some reason, but the same sketch is working great on the Arduino Uno (with different pin assignment - 2, 3, 4).

Can someone explain to me what is the issue with the sketch?

const int PinA = 14; // Used for generating interrupts using CLK signal
const int PinB = 12; // Used for reading DT signal
const int PinSW = 13; // Used for the push button switch

int lCnt = 0; // Keep track of last rotary value
volatile int vPos = 0; // Updated by the ISR (Interrupt Service Routine)

void isr_event ()  {
  static unsigned long lIsrTmr = 0; // Last Interrupt time
  unsigned long IsrTmr = millis(); // Interrupt time

  // If interrupts come faster than 5ms, assume it's a bounce and ignore
  if (IsrTmr - lIsrTmr > 5) {
    if (digitalRead(PinB) == LOW)
    {
      vPos++ ; // Could be +5 or +10
    }
    else {
      vPos-- ; // Could be -5 or -10
    }

    // Restrict value from 0 to +100
    vPos = min(10, max(0, vPos));

    // Keep track of when we were here last (no more than every 5ms)
    lIsrTmr = IsrTmr;
  }
}

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

  // Rotary pulses are INPUTs
  pinMode(PinA, INPUT);
  pinMode(PinB, INPUT);

  pinMode(PinSW, INPUT_PULLUP); // Switch is floating so use the in-built PULLUP so we don't need a resistor

  attachInterrupt(digitalPinToInterrupt(PinA), isr_event, LOW); // Attach the routine to service the interrupts

  Serial.println(F("Starting..."));  // Ready to go!
}

void loop()
{

  // Is someone pressing the rotary switch?
  if ((!digitalRead(PinSW))) {
    vPos = 0;
    while (!digitalRead(PinSW))
      delay(10);
  }

  // If the current rotary switch position has changed then update everything
  if (vPos != lCnt) {
    // Write out to serial monitor the value and direction
    Serial.println(vPos);
    // Keep track of this new value
    lCnt = vPos ;
  }
}

The ESP8266 doesn't know what a "LOW" interrupt is.  You will have to change your code to use FALLING, RISING or CHANGE interrupts only.


Why can't I switch off the LED immediately using this sketch? I hope the LED can fade out a period of time. Also, I hope I can switch off the LED immediately when it is fading, but I only can fade out.

const int buttonPin = 2;
const int ledPin = 9;
const int fadingDelay = 20000;
int buttonState = 0;
boolean fadingState = false;
void setup() {

// initialize the LED pin as an output:
  pinMode(ledPin, OUTPUT);
  // initialize the pushbutton pin as an input:
  pinMode(buttonPin, INPUT);
}
void loop() {
  // read the state of the pushbutton value:
  buttonState = digitalRead(buttonPin);

  // check whether the button was pressed
  if (buttonState == HIGH) {
    buttonState = LOW;
    // check the current LED status (on/off)
    if (fadingState == false) {
      // turn on the LED
        for (int i = 255; i >= 0; i -= 5) {
          if (buttonState == HIGH && fadingState == true) {
          analogWrite(ledPin, 0); //immediately off
          i=-1;
          }
        analogWrite(ledPin, i);
             delay(fadingDelay);

    }
    fadingState = false;  // save the current LED state (on/off)
  }
}
}

I can't see anywhere where you are assigning fadingState as true.I can't understand this part

if (fadingState == false) {
      // turn on the LED
        for (int i = 255; i >= 0; i -= 5) {
          if (buttonState == HIGH && fadingState == true) {
          analogWrite(ledPin, 0); //immediately off
          i=-1;
          }
    analogWrite(ledPin, i);
    delay(fadingDelay);
    }

If you are entering in a if condition with statement fadingState as false. Then in for loop you are having a if condition in which statement is fadingState == true.If you are entering in as a False then why are you looking for True Condition.

Then if you manage to sort that add break; in that if condition so that when LED turns OFF you will exit that for Loop.

And Here you are setting the button state as low buttonState = LOW if first If condition, then in that nested if without reading the buttonState you still looking for it as HIGH.


Sanity check for dual IR LED circuit If the intent is to drive the two LED's with 200-400mA (using PWM @ 38Hz), is there anything wrong with this solution?

Perhaps this is a better solution, as it ensures the current is exactly the same for the two LED's (so that they are not out of phase with each other):

I would use a single transistor rated at minimum 1A continuous (a MOSFET by choice), and have both LEDs switched in parallel with their own resistor.  By having them in series as in your second schematic you are limiting the input voltage to a minimum of 2×Vf which could be as high as 5.2V, and thus more than your power source can provide.

simulate this circuit – Schematic created using CircuitLab

This gives the same result as your first circuit, but only uses one transistor for the switching. You can add more LED+Resistor pairs in parallel as you like as long as the total current is below that which the chosen MOSFET can handle.

You should rate the MOSFET to handle the maximum continuous current, not the pulse current, in case the output of the Arduino should be set continuously HIGH instead of sending PWM.

You should also note that the pulse current of an LED is usually rated at 1% duty cycle.

Also note that as the voltage of your power source drops, so will the voltage across the resistors, and thus the current flowing through them (and your LEDs) making the LEDs dim.  It may be beneficial to first pass your battery power through a high-efficiency 3.3V switch-mode regulator to keep the voltage stable whilst wasting the minimum amount of power in the regulation.


How to control MKR1000 from outside your local network I want to send an HTTP command to MKR1000 from outside my local network.

So far, all the googled resources point to getting the local IP (example 192.168.0.10) of MKR1000 and sending a command like http://192.168.0.10/H to it and then parse it.

How do I send a command to MKR1000 from outside its local network?

I should clarify that I want this to be a consumer product and can't have the end-user fiddling with their routers for port forwarding etc.

The only way I can think of to achieve this would be to port forward your router, and forward port 80 (http) to your MKR1000. You can check out https://portforward.com/ for instructions on that.

If you don't want to port-forward, you'd have to have the MKR1000 connect to a centralized IOT server somewhere, and have the user go through the server to access the MKR1000. That's how other iot devices such as nest cameras do it.


What is the best vehicle platform to begin with (e.g. tracked, four-wheel drive) Despite many articles on the topic of vehicle platforms, none of them seem to recommend the best one to start with. Later on I am sure I will seek an exact kind of chassis for autonomous vehicle construction, but now I am looking to learn the basics of this area of the Arduino world. If you could give me a simple recommendation for the general category of vehicle platform to use it would be much appreciated. I will be using an ultrasonic distance sensor coupled with a servo motor to detect obstacles, so it is a very simple project. Thank you so much.

SparkFun's Magician Chassis is a very simple, very flexible chassis for starting out. Also comes as part of the RedBot Kit.


FSR wiring using internal pullup resistors? What are the disadvantages to using Arduino's internal pullups with a force force sensitive resistor (FSR) sensor?

All the wiring examples I see for FSRs place the sensor on the high side and use a 10k pulldown resistor. Searching Google, I can find virtually no one who places the FSR on the low side and uses the internal pullup. Since this would reduce complexity by using one less wire and resistor, I have to assume there's some big downside I'm not seeing. Why shouldn't you use the internal pullup?

I've worked with conventional potentiometers in the 100k ohm range, and I've found that with values that high, the Arduino's ADC finds a lot of noise, resulting in a sensor value that jitters and drifts. I found that the only reliable way to get a stable ADC value is to use a potentiometer with a maximum value of 10k or less. Since the FSR's range is up to 1M ohms, I'm worried I won't be able to get a stable reading. Does wiring it via the high side or low side effect this? What can I do to minimize noise from the FSR, other than shielding the sensor cable or adding a capacitor between the signal a and ground wire?

There is probably no practical difference concerning high side vs low side (except the Arduino Uno only has a pullup, and no pulldown).

The issue would be the accuracy of the pullup (graphs in the datasheet show variations of 10% with temperature) vs the accuracy of the resistor (1% is now commonplace).

The pullup is usually a current source, not a specific resistor value. Even if the supply voltage is not known, the maths involved with solving a known resistor is series with an unknown resistor is quite straightforward.

Short answer, using the pullups would probably work, but you would have to confirm accuracy, calibration and even repeatability, while this is already well known for a resistor.

Datasheet, see graphs on p412:

http://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-42735-8-bit-AVR-Microcontroller-ATmega328-328P_Datasheet.pdf


Use ATTiny as a battery-backed RAM? So, I found an interesting article the other day, and I'm trying to build a project that could benefit from a battery-backed memory (no wear limits, but keeps data over power cycling). The article lists how an extremely small current from an LED (acting as a photocell in the lit room) accidentally powered the AVR during a RAM-endurance test.

But, what if this is done on purpose with a battery?

(Article here: https://wp.josh.com/2014/03/03/the-mystery-of-the-zombie-ram/)

The problem with this idea (since the RAM can already be backed up, as shown in the article, though the author does not seem to have considered this) is that I need a way to keep an array of memory ignored by the C initializer. It would be the height of hilarity to have the memory survive the power-off event only to be nuked by the chip's powerup reset code. The listed example at that article would work, for the first requirement, but would break almost anything else I might try to do (since it overrides the entire initializer). (Comment on the reset issue: https://wp.josh.com/2014/03/03/the-mystery-of-the-zombie-ram/#comment-598)

Also, assuming I tried this, would I simply damage the pin rather than provide power? I plan to use a pin continually set to input attached to the positive side of a lithium coin cell, with a common ground. In theory, powering the AVR (and I think at any voltage) through the VCC pin would cause the chip's diodes to disconnect the battery, but if it's unplugged, the core would receive enough power to keep the RAM alive.

Of course, my question is whether it would instead stupidly try to keep the core running when power is disconnected (in the original article, the nanowatts from the LED couldn't do that, so it's forced to shut down, but I don't know if this is solely due to power limits or if it would shut down the main systems if there's no connection over VCC). In this case, it might try to draw more than the 1mA rating over that parasitic supply, and try to power the entire chip when I don't want it to (thus frying the clamping diode or something equally bad).

I wonder if it would be possible simply to put a large resistor (10K? 1M?) in series with the battery in this case? That would automatically limit the supply to less than 1mA.

Expanding on my previous comment...

  I need a way to keep an array of memory ignored by the C initializer

You can achieve this by instructing the compiler to store the array in
the “.noinit” memory section:

int my_array[ARRAY_LENGTH] __attribute__((section(".noinit")));

Your array will end up sitting somewhere between the .bss and the heap
(if any), and will not be touched by the __do_clear_bss routine from
the C startup code.

  my question is whether it would instead stupidly try to keep the core
  running when power is disconnected

Most likely. In order to avoid that, I suggest you enable the brown-out
detection by setting the BODLEVEL fuses. This feature of the
ATtiny is specifically meant to prevent the CPU core from running if the
supply voltage is below some configurable threshold.


How to use get_properties to get RSSI in RF24? As picture below, how to use get_properties ? I fail to understand AN625, how to use get_properties to get RSSI ?

Adding source code based on RH_RF24 functions.

#include <SPI.h>
#include <RH_RF24.h>

// Singleton instance of the radio driver
RH_RF24 rf24;

uint8_t Recieve_Data[20];

uint8_t receive_buffer[RH_RF24_MAX_MESSAGE_LEN];
uint8_t receive_buffer_length = sizeof(receive_buffer);

uint8_t Rssi;

unsigned long Micro_Time;

uint8_t status[8];
uint8_t buf[RH_RF24_MAX_MESSAGE_LEN];
uint8_t len = sizeof(buf);

void setup()
{
  Serial.begin(115200);
  if (!rf24.init())
    Serial.println("init failed");
  // Defaults after init are 434.0MHz, modulation GFSK_Rb5Fd10, power 0x10
   while(!rf24.setFrequency(443));
  rf24.setModemConfig(rf24.GFSK_Rb50Fd100);  //设置成GFSK_Rb50Fd100
}

void loop()
{
  rf24.setModeRx();
  delay(100);
  rf24.setModeIdle();
  rf24.command(RH_RF24_CMD_GET_INT_STATUS, NULL, 0, status, sizeof(status));
  Serial.print("Id   ");
  for (int i = 0; i <= 8; i++)
  {
    Serial.print((uint8_t)status[i]);
    Serial.print("   ");
  }
  Serial.println();
  /*
    if (status[2])
    {
      uint8_t modem_status[6];
      rf24.command(RH_RF24_CMD_GET_MODEM_STATUS, NULL, 0, modem_status, sizeof(modem_status));
      delay(100);
      for (int i = 0; i <= 6; i++)
      {
        Serial.print(modem_status[i]);
        Serial.print("   ");
      }
      Serial.println();
    }
  */
  delay(400);
}

By using the RH_RF24 rf24;(Singleton instance of the radio driver), read a series of properties is really simple.

The properties shall be in the same GROUP,
Up to 16 properties could be read in the same request,

  Hereafter is a example to read from SYNC_CONFIG to SYNC_BITS_7_0 (5
  properties).

Step 1 - Declare your own uint8_t sync_stat[5]; or use the still declared uint8_t status[8];.

 uint8_t sync_stat[5];

Step 2 - The firstProperty is in fact the first property to be read and count is the number successive properties to be read (from SYNC_CONFIG = 0x1100 to SYNC_BITS_7_0 = 0x1104.

// And check the returned code
if (rf24.get_properties(SYNC_CONFIG,sync_stat,5)) {
    // sync_stat[0]= SYNC_CONFIG
    // ...
    // sync_stat[4]= SYNC_BITS_7_0
}

  Then, the equivalent command() is:

uint8_t buf[3];
buf[0] = SYNC_CONFIG >> 8;
buf[1] = 5;
buf[2] = SYNC_CONFIG & 0xff;
if (rf24.command(RH_RF24_CMD_GET_PROPERTY, buf, sizeof(buf),sync_stat,5)) {
    // Same array
}


Sending a text message through a arduino wifi shield I am using an Arduino uno and need to send text messages and email messages from the device based on certain events occurring.  I have the logic figured out of when to send the text message or email but don't know what shield I need to send these messages.

Sending an email you need a network connection of some form.  Options include:

Ethernet Shield
WiFi Shield
GSM Shield (can be expensive, but will work almost anywhere)

To send a text message you need access to a text message service. That can either be directly through a mobile phone operator or through an on-line SMS gateway service. For an on-line service the options are as above, since it's almost the same as sending an email (in fact, some gateways offer an email-to-SMS gateway option). For direct mobile provider access you can only use a GSM shield.

So really it boils down to how mobile you need it to be, and how much you are willing to spend (both on the initial hardware outlay and service provider fees and charges).


How do you make a Class variable array bigger? I am making an infrared macro-keyboard, I want to store Unicode for the Keyboard class in an array inside a class I made called Keybindand to allow the user to program as many outputs as they want, I want the storage to be mutable.  I currently use the String class and decode within the program but it's cpu intensive and not very practical.
I want to use an array or list, but I haven't found any way to expand the size of an array inside a class.  Casting a temporary array didn't work:

  int intArray[] = {0,1,2,3,4,5};
  int* temp[7];

  for(int x = 0; x<sizeof(intArray)/sizeof(intArray[0]); x++){
    temp[x] = intArray[x];
  }
  temp[6] = 6;
  intArray = temp;

IDE spits out "incompatible types in assignment of 'int* [7]' to 'int [6]'"

I want to [...] allow the user to program as many outputs as they want

This may be problematic. The microcontroller has a limited amount of
RAM: it will not be able to store arbitrarily long macros. You should
consider a way of telling the user “sorry, no more memory”. Or you can
be optimistic and assume the user will never try to record macros long
enough to exhaust the memory... and let the firmware crash if this
assumption turns out to be invalid.

  I currently use the String class and decode within the program but
  it's cpu intensive and not very practical.

CPU intensive? You mean the allocation? Reading the contents of a String
object is not CPU intensive. And what do you find impractical in the
String class? At it's core, it's just a dynamically sized container for
character data, which seems to be exactly what you are looking for.

  I haven't found any way to expand the size of an array inside a class.

A class is a data structure of fixed size. There is no way you can
expand its contents. If you need something of variable size, you will
have to use dynamic allocation. You will then only store a pointer to
the allocated memory in your class. This is exactly what String does.
The only other option is to store an array of fixed size within the
class, and make that size large enough so that you never need more.


I have the code printing the data I need but don't know how to connect the data on ESP8266 IP web server #include "DHT.h"
   #include "NewPing.h"
   #include <SoftwareSerial.h>

   #define DEBUG true
   SoftwareSerial esp8266(11,10);
   #define DHTPIN 2        // DHT-11 Output Pin connection
   #define DHTTYPE DHT11   // DHT Type is DHT 11 (AM2302)
   #define TRIGGER_PIN 4
   #define ECHO_PIN 3
   #define MAX_DISTANCE 400

    NewPing sonar(TRIGGER_PIN,ECHO_PIN,MAX_DISTANCE);
float hum;
float temp;
    DHT dht(DHTPIN, DHTTYPE);

void setup() {

   Serial.begin (9600);
   dht.begin();

   pinMode(TRIGGER_PIN, OUTPUT);
   pinMode(ECHO_PIN, INPUT);

   sendData("AT+RST\r\n",2000,DEBUG);
   sendData("AT+CWMODE=2\r\n",1000,DEBUG);
   sendData("AT+CIFSR\r\n",1000,DEBUG);
   sendData("AT+CIPMUX=1\r\n",1000,DEBUG);
   sendData("AT+CIPSERVER=1,80\r\n",1000,DEBUG);

 }

 void loop()

 {

 delay(2000);  // Delay so DHT-11 sensor can stabalize

   hum = dht.readHumidity();  // Get Humidity value
   temp= dht.readTemperature();  // Get Temperature value

 digitalWrite(TRIGGER_PIN, LOW);
 delayMicroseconds(2);
 digitalWrite(TRIGGER_PIN, HIGH);
 delayMicroseconds(10);
 digitalWrite(TRIGGER_PIN, LOW);

   long duration,distance;
   duration= pulseIn(ECHO_PIN,HIGH);
   distance = duration/58.2;

   Serial.print("Humid: ");
   Serial.print(hum);
   Serial.print(" %, Temp: ");
   Serial.print(temp);
   Serial.print(" C, ");
   Serial.print("Distance: ");
   Serial.print(distance);
   Serial.println(" cm");

   delay(50);

  if(esp8266.available())

   is sending a message
 {
   if(esp8266.find("+IPD,"))
 {
 delay(1000);

 int connectionId = esp8266.read()-48;

  /* We are subtracting 48 from the
  output because the read() function returns
  the ASCII decimal value and the
  first decimal number which is 0 starts at 48*/

  String webpage = "
IOT Garbage Monitoring System
";
  webpage += "

";

  if (distance<5)
 {
  webpage+= " Trash can is Full";
 }
   else{
   webpage+= " Trash can is Empty";
    }
   webpage += "

";
   String cipSend = "AT+CIPSEND=";
   cipSend += connectionId;
   cipSend += ",";
   cipSend +=webpage.length();
   cipSend +="\r\n";

   sendData(cipSend,1000,DEBUG);
   sendData(webpage,1000,DEBUG);

   String closeCommand = "AT+CIPCLOSE=";
   closeCommand+=connectionId;
   closeCommand+="\r\n";
   sendData(closeCommand,3000,DEBUG);

   }
   }
   }

   String sendData(String command, const int timeout, boolean debug)

   {

   String response = "";
   esp8266.print(command);
   long int time = millis();

   while( (time+timeout) > millis())
   {
   while(esp8266.available())
   {
   char c = esp8266.read();
   response+=c;
   }
   }
   if(debug)
      {
     Serial.print(response);
      }
     return response;
      }

The esp-01 is in AP mode. To access the web page on the IP address 192.168.4.1 show in Serial Monitor you must connect to the WiFi network created by the esp-01.

If you click the WiFi icon in the bottom right corner of Windows, you will see a list of WiFi networks.


Getting a random number for electronic dice I am making a "Electronic Dice".

I have 7 LEDs to form the output, and this works fine.

My problem is getting a random result on the output.

int die_face = 1;

void loop()
{
    if (analogRead(BUTTON_PIN) == HIGH)
    {
        paintDieFace((die_face % 6) + 1);
    }

    die_face += 1;
}

The problem is, that roughly 95% of the time I get a 1.
Most of the time it's not a 1, it's a 2, or very rarely a 3.

I've tried paintDieFace() with millis()%6+1 too, but always get the same result.
When it's painted with random(1,7); I get 1, 2 or 3 100% of the time.

Is this some sort of timing issue?  I just don't get it.

Just to clarify - The paintDieFace() function is working perfectly, I'm logging the result to serial too.

First of all, look at this line of code:

if (analogRead(BUTTON_PIN) == HIGH)

You probably want to use digitalRead(). Note that it is okay to use digitalRead() on an analog pin, just make sure to use the right pin number (A0, etc.)

From the Arduino Source:

#define HIGH 0x1
#define LOW  0x0

(Ignore the 0x, that is just specifying that it's hexadecimal. However, 0 and 1 are the same in any base)

So, really, this function is only activated when analogRead() returns 1, which could possibly cause a problem later if it doesn't check at the right time. Note: now is a good time to remind you about debouncing...

For your actual code, since you want it to be simple, I suggest you forget that code that you wrote. Arduino has a built in random library, which works unless you have some special need for a random number.

Your final code should look like something like this in the end:

void loop() {
    if (analogRead(BUTTON_PIN) == HIGH) {
        paintDieFace(random(1, 6);
    }
}

Note that you should also use this code here in your setup (make sure that analog pin is floating: nothing should be attached to it):

randomSeed(analogRead(A1));

It actually isn't random, just pseudo-random. That means it relies on an equation to generate what seem to be random numbers. Because there has to be a default value of where the equation starts (the seed), it will repeat the same numbers every time you run it.

If you're wondering how this works, know that the analog pin is affected by a ton of external factors when there is no other electric signal attached.


Mkr1010 disconnects and reconnects normally until it reaches a point where it never reconnects again The board does reconnect from time to time, but there are times where it just disconnects and never reconnects again and I can't replicate the error because while I run it with Serial open and turn ON and OFF my WiFis he always reconnects as it should.

#include <ArduinoHttpClient.h>
#include <WiFiNINA.h>
#include <EmonLib.h>

EnergyMonitor emon1;
EnergyMonitor emon2;
EnergyMonitor emon3;
int INTERVAL = 60;
int last_code = 0;

char ssid[] = "MySSID";
char pass[] = "MyPW";

String ID = "Garden_Pump_Sensor";

int sequence = 0;
double kWh = 0.0;

char serverAddress[] = "192.168.1.108";  // server address
int port = 5005;

WiFiClient wifi;
HttpClient client = HttpClient(wifi, serverAddress, port);

int status = WL_IDLE_STATUS;

void setup() {
  Serial.begin(9600);
  analogReadResolution(9);
  emon1.current(0, 100);
  emon2.current(5, 100);
  emon3.current(6, 100);
  Connecting();

}
void Connecting() {
  int tries = 4;
  while ( (WiFi.status() != WL_CONNECTED && tries > 0) || last_code != 200) {
    Serial.print("Status #1: ");
    Serial.println(WiFi.status());
    WiFi.begin(ssid, pass);
    Serial.print("Status #2: ");
    Serial.println(WiFi.status());
    tries--;
    last_code = 200;
  }

  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());
  IPAddress ip = WiFi.localIP();
  Serial.print("IP Address: ");
  Serial.println(ip);
}

void reconnecting() {
  if  (WiFi.status() != 3  || (WiFi.RSSI() <= -90) || (WiFi.RSSI() == 0) || last_code != 200) {
    WiFi.end();
    Connecting();
  }
}

void loop() {
  unsigned long delayTime = INTERVAL * 1000;
  unsigned long time_start = millis();

  DataMonitorAndSend();

  unsigned long time_final = millis() - time_start;
  unsigned long delay_value = delayTime - time_final;
  Serial.println(delay_value);
  if (delay_value < 1  || delay_value > delayTime) {
    return;
  } else {
    delay(delay_value);
  }

}
void DataMonitorAndSend() {
  reconnecting();

  Serial.println("making POST request");
  String contentType = "application/json";
  kWh = kWh + getKWH();
  String postData = "{\"ID\": \""+ID+"\",\"seq\": " + String(sequence) + ",\"kWh\": " + String(kWh, 6) + "}";
  Serial.print("data: ");
  Serial.println(postData);

  client.setHttpResponseTimeout(5 * 1000);
  client.post("/receivedata/", contentType, postData);

  // read the status code and body of the response
  int statusCode = client.responseStatusCode();
  String response = client.responseBody();

  Serial.print("Status code: ");
  Serial.println(statusCode);
  if (statusCode == 200) {
    kWh = 0;
    sequence++;
  }
  last_code = statusCode;
  Serial.print("Response: ");
  Serial.println(response);

}

double getKWH() {
  int LOOPS = 15;
  double kWh_Total = 0.0;
  unsigned long delayTime_kwh = 2 * 1000;
  for (int i = 0; i < LOOPS; i++) {
    unsigned long time_start_kwh = millis();

    double Irms1 = emon1.calcIrms(600);
    if (Irms1 < 0.3) Irms1 = 0;
    double Watt1 = (Irms1 * 230) / 1000;

    double Irms2 = emon2.calcIrms(600);
    if (Irms2 < 0.3) Irms2 = 0;
    double Watt2 = (Irms2 * 230) / 1000;

    double Irms3 = emon3.calcIrms(600);
    if (Irms3 < 0.3) Irms3 = 0;
    double Watt3 = (Irms3 * 230) / 1000;

    kWh_Total = kWh_Total + ((Watt1 + Watt2 + Watt3) / 60);

    unsigned long time_final_kwh = millis() - time_start_kwh;
    unsigned long delay_value_kwh = delayTime_kwh - time_final_kwh;
    if (delay_value_kwh < 0  || delay_value_kwh > delayTime_kwh) {
      delay(0);
    } else {
      delay(delay_value_kwh);
    }

  }

  return kWh_Total / LOOPS;
}

Feel free to ignore the getkWH(), it's code related to power consumption. Also the firmware is up to date and the server is running in a static IP.

I found that before using WiFi.begin() to re-connect, one needs to use WiFi.disconnect() first. At least that keeps my set-up reliably re-connecting, when its battery is empty or my router is out for a moment. Also, testing for WL_CONNECTED or 3 only means that one's set-up is connected to the router, but the router not necessarily yet to the internet; in case of a restart of the router after a power outage. On one of my routers, one has to wait 10 seconds, on another 18 seconds.

void connectToWLAN()
{
  // Check if the AirLift FeatherWing's WLAN module works
  if (WiFi.status() == WL_NO_MODULE)
  {
    Serial.println("Connection to AirLift FeatherWing WLAN module failed");

    // If not, indicate there is a WLAN module malfunction
    WiFi.setLEDs(0, 255, 0); // Red

    // And stop forever
    while (true);
  }

  // Return to loop() if already connected to the WLAN router
  if (WiFi.status() == WL_CONNECTED)
  {
    return;
  }

  Serial.println("Trying to connect to WLAN router");

  // Indicate there is no WLAN router connection just yet
  WiFi.setLEDs(192, 255, 0); // Yellow

  do
  {
    // Start connection to WLAN router and print a status value
    WiFi.disconnect();
    delay(1000);

    status = WiFi.begin(WLAN_SSID, WLAN_PASS);
    // WL_IDLE_STATUS     = 0
    // WL_NO_SSID_AVAIL   = 1
    // WL_SCAN_COMPLETED  = 2
    // WL_CONNECTED       = 3
    // WL_CONNECT_FAILED  = 4
    // WL_CONNECTION_LOST = 5
    // WL_DISCONNECTED    = 6
    Serial.println(WiFi.status());
    delay(10000);
  }
  while (status != WL_CONNECTED);

  Serial.println("Connection to WLAN router successful");

  // Indicate that the WLAN router connection was established
  WiFi.setLEDs(255, 0, 0); // Green

  // To better see the status indicating RGB LED's state
  delay(2000);
}


Pushbutton and switch case I am developing a project for my college.

PROJECT OUTLINE:
There are 3 sensors (Temp., Accelerometer & Humidity) will read the respective parameters continuously. in between if I press 'PushButton1' for 2 seconds  the Arduino must enter into programming mode.

The programming mode has 6 Switch cases. Each case gets selected one after one on the even of 'PushButton1' gets pressed for short time.

Also if I press 'PushButton1' again for 2 seconds in Programming mode the Arduino should come out of the programming mode.

PROBLEM:
In my current sketch I have to press 'PushButton1' for 2 seconds in Programming Mode for 2 seconds to change the case. Also I don't understand how to get out of the Switch Case loop.

The sketch is attached with this topic.

const int btn = 2;
const int ledPin =  13;
int selector = 0;
boolean  volatile wait = false;
const unsigned long event=2000;
unsigned long a=0;
unsigned long b=0;
unsigned long c=0;
void setup()
{
Serial.begin(9600);
pinMode(ledPin, OUTPUT);
pinMode(btn, INPUT);
attachInterrupt(digitalPinToInterrupt(btn),decoder,CHANGE);
}

void loop()
{
  while(wait) {  }
  if (digitalRead(btn) == LOW) {
    a = millis();
  }
  else
  {
    b = millis();
    c=b-a;
    Serial.println(c);
        if (c>=event)
            {
              doSwitchStatement();
              selector++;
              if (selector >6)
                  {
                  selector = 0;
                  delay(500);
                  }
            }
  }
  wait = true;
  interrupts();

}

void decoder()
{
  noInterrupts();
  wait = false;
}

void doSwitchStatement()
{
  switch(selector)
  {
  case 0:
    Serial.println("Case 0");
    break;

  case 1:
    Serial.println("Case 1");
    break;

  case 2:
   Serial.println("Case 2");
    break;

  case 3:
   Serial.println("Case 3");
     break;

  case 4:
   Serial.println("Case 4");
    break;

  case 5:
  Serial.println("Case 5");
    break;

  case 6:
  Serial.println("Case 6");
    break;

  }
}

I would do it as a simple state without the blocking while
define two bools

bool buttonPress = false;
bool inMenu = false;

and add it to the loop.To differentiate between different press lengths you need to define them. There is nothing like an "automatic" short press recognition. Also use variables which are "speaking" making it easier to read code for others.

const unsigned long buttonPressLong = 2000;  // 2 seconds
const unsigned long buttonPressShort = 250;  // 0.25 secondis feasable
const unsigned long buttonPressDebounce = 50;
// debouncing for too short presse Thanks Edgar Bonet
unsigned long buttonPressStart = 0;

The program below does what you want (tested on my uno test lab). As Edgar Bonet commented before you should also debounce the button (look it up in WiKi) to exclude unwanted effects The times I use are practical on my hardware, so you could play around by looking at the serial monitor.

const int btn = 2;
const int ledPin =  13;
int selector = 0;
const unsigned long buttonPressLong = 2000;  // 2 seconds
const unsigned long buttonPressShort = 250;  // 0.25 secondis feasable
const unsigned long buttonPressDebounce = 50;  // debouncing for too short presse Thanks Edgar Bonet
unsigned long buttonPressStart = 0;

bool buttonPress = false;
bool inMenu = false;

void setup() {
  Serial.begin(9600);
  pinMode(ledPin, OUTPUT);
  pinMode(btn, INPUT);
  }

void loop() {
  if (digitalRead(btn) == LOW && !buttonPress ) {
    buttonPressStart = millis();
    buttonPress = true;
  }
  // The routine is only triggered if a previous pressing took place, otherwise it's ignored
  else if (digitalRead(btn) == HIGH && buttonPress) {
    if (millis() - buttonPressStart > buttonPressLong && millis() - buttonPressStart > buttonPressDebounce && inMenu) {
      Serial.print("Long press: ");
      Serial.println(millis() - buttonPressStart);
      buttonPress = false;
      inMenu = false;
    }
    if (millis() - buttonPressStart < buttonPressShort && millis() - buttonPressStart > buttonPressDebounce && !inMenu) {
      Serial.print("First short press ");
      inMenu = true;
    }
    if (millis() - buttonPressStart < buttonPressShort && millis() - buttonPressStart > buttonPressDebounce && inMenu) {
      Serial.print("Short press: ");
      Serial.println(millis() - buttonPressStart);
      doSwitchStatement();
      selector++;
      if (selector > 6) {
        selector = 0;
        delay(500);
      }
      buttonPress = false;
    }
  }
  // Here you could do other stuff as it is non blocking
}
doSwitchStatement(){...}// Stays the same as yours

Look at the code used as it is non blocking (of course there is room for improvement) but as a starter for your further experiments ...


Why does my Arduino seem to reboot every time that I open Serial Monitor? Every time that I open the Serial Monitor, my Arduino Uno, seems to go back to void setup(). Is it a normal thing?

That is a normal feature of Arduinos, not an error. I find it mildly annoying sometimes, but it's nice for interactive programs that want some kind of menu message to be the first thing you see in the terminal.

If you want help disabling the auto reset, your options are detailed in Disabling Auto Reset On Serial Connection.


MAX7219 powered on via digital pin set to HIGH is not working good (I < 25mA) I'm using 7-segment 8-digits MAX7219 eBuy module in my battery-supplied ATMega168P project to output some readings. MAX7219 in powerdown mode draws ~150uA (as stated in the datasheet) which is too much for me, because the rest of the circuit draws less than 1uA is sleep mode. So I decided to power off Vcc line for MAX7219 before entering sleep, and power it on just after wakeup.

Current draw for the software-dimmed display module is only 15..19 mA in my case, which is far less than 40mA pin maximum for ATMega168P, so I connect display Vcc line to one of digital pins and power it on at setup():

void setup()
{
  pinMode(4, OUTPUT);
  digitalWrite(4, HIGH);
}

However, display module works only 1..3 seconds after starting, then switches off. I checked display Vcc — 4.9V, but the display is off. (I turned off enterng to sleep mode for a while)

This display module doesn't have capacitors C3 and C4 between Vcc and GND (but there's a placeholder for it), recommended in some sources. I solder two capacitors of 100nF and 4,7uF in parallel. It helps only a little: after 1..2 seconds of normal working display shows only digit #0 and in much higher brightness than I set (see the photo).

I may only suggest my cheap multimeter is wrong and the display draws much more, but I dont know how to check it. Rset is 10k on this module, btw.

Why does it happen?
Is there a way to solve the issue without using a transistor / MOSFET / relay (I suppose it should obviously help).

EDIT: If the display is powered directly by controller Vcc it works correctly as expected. It's current draw is 15..20mA.

After some research I eventually solved my problem, so here's the answer.

  Why does it happen?

This LED display draws much more current than I measured on Vcc line between Arduino and display because of ghost powering via signal lines (DIN, LOAD, CLK). The display (although slightly dimmed) can even run without Vcc line connected! Real current draw was about 30-40 mA with peaks up to 100 mA.

  Is there a way to solve the issue without using a transistor / MOSFET / relay (I suppose it should obviously help).

Yes, by limiting display current draw.

For an unknown reason these cheap MAX7219-driven LED boards has very small current control resistor RSet of 10 kOhm, resulting in huge Iseg ~= 40 mA. Replacing it by something like 62k will limit per-segment current to ~10 mA.

This is what the datasheet says:

And this is how it can be done:

Works perfectly! Now I can power off LED display completely, so it consumes no current when the device is sleeping.

NOTE: it's important to properly re-initialize MAX7219 after power on!

In the colorized table above one could find display current draw for different software-set intensity settings in case of using RSet = 62k. GND line values (blue column) seems to be correct as they well correspond with overall device's current draw (the most correct measurement, I suppose).


How does DDRD |= _BV(PD2) differ from digitalWrite(2,HIGH)? I'm attempting to copycat the work of Louis Frigon's Toyota Aux Enabler. I have (with a lot of help on this site) managed to begin capturing and understanding messages on the AVC-LAN bus, but I can't quite send messages.
Frigon uses the following line to drive output signal to high:

DDRD |= _BV(PD2) | _BV(PD3);

I have more or less no idea what this means. He then 'releases the output' with the following:

DDRD &= ~( _BV(PD2) | _BV(PD3) );

If I copy these lines verbatim I don't get the same results. If I set the output high and then read the bus, I don't even see the signal I'm putting out. I wonder if this is related to the differences between his Atmega8 and my Arduino Nano?

I can't paste my or Frigon's work here due to character count limitations, so here is his github for the project: https://github.com/halleysfifthinc/Toyota-AVC-LAN

The most important files to my question are BigSchematic.jpg and AVCLanDriver.c.

Here is a dump of my current code: https://pastebin.com/NG9U5FuL

Here is my schematic: https://imgur.com/a/HBkK7

Each port on the ATmega328P (or the ATmega8 for that matter) is
controlled by two registers¹:

DDRx, where x is B, C or D, is the “data direction register”. It is
used to set the pin to either input or output. Writing to this
register is roughly equivalent to calling pinMode().
PORTx is the port's “data register”. It is mostly used in output
mode to set the pin to HIGH or LOW. Writing to this register is
equivalent to calling digitalWrite().

All this is covered by the Arduino tutorial on direct port access.
And, of course, by the datasheet; more specifically by
section 18.2: “Ports as General Digital I/O”.
As you may now notice, the original code does not use anything like
digitalWrite() to write to the bus, relying instead of the equivalent
of pinMode(). This is related to the electrical characteristics of the
bus:

You write a “physical 1” by actively driving AVC+ high and AVC− low
You write a “physical 0” by releasing the bus, in which case the
potentials of those lines are set by the termination resistors.

That's why you see InitMCU() setting PORTD for driving AVC+ high and
AVC− low, but leaving DDRD in its initial state (“leave pins
tri-stated” says the comment). At this point the bus is in the
“released” state. Then pulses are sent by setting the pins to output
mode (“Drive output to signal high” in the comment) and, after an
appropriate delay, setting them back to input mode (“Release output”).

¹ I am leaving away the details that are irrelevant to the code in
question, like the internal pullup or pin toggling via PINx.


Brownout with Arduino Nano I'm making an RC car with the Arduino Nano. I'm using RF433 as  wireless communication with 2 motors and L293D as the motor driver. I use 4 1.5V batteries to power the Arduin and another 6V battery pack to power the motors, and a joystick with an Arduino Mega to send commands through the RF433 to the Arduino Nano.

I've written a program that sends specific digits when the joystick is in a certain position, i.e. when the joystick is "bent" to the front it sends a "1", a "2" is sent when the joystick is bent towards the back, and so on.

My problem is this:

When I bend the joystick towards a certain direction, the RC car moves accordingly without problem; However, when I bend the joystick towards another direction the RC car doesn't respond.

I took a look at what the RC car was receiving, and I've noticed that after the first command was sent (when I bend the joystick towards a certain direction), no more commands get to the RC car (in other words the Arduino Nano), and this occurs occasionally. I think this means the Arduino Nano "froze" after the first command.

You have at least three problems here:

1) First and most critically, a nominal 6v pack does not meet the input voltage requirements of the regulator used an Arduino even before it gets loaded down by a motor, and it only gets worse under load

2) L293/L297 and similar bipolar bridges have absurdly high internal losses, so are unsuited to low voltage systems - effectively one of your cells goes just to feeding the wasteful driver chip.  Use a modern and efficient FET driver like a TB6612FNG, or else add another cell to the pack.

3) The 433 MHz RF modules are notoriously low fidelity, and in many places not permitted for the control of RC models anyway.  You'll have much better results with the sophisticated digital radio modules sold at comparable prices for 2.4 GHz, which are incidentally the functional equivelent of what most RC toys now use (and actually in many cases can be made interoperable with them).

Granted, you may well have other issues as well, such as errors in your software.


All voltage directed to pin 3 when multiple pins are set to out put I just finished testing a haptic device at university, and when I took it home I got the joy of finding the device not working. Here's what I can trace the problem to: when multiple pins are set to output (pin 2~11), pin 3 writes constantly to high and there is nothing I can do to make it stop.

Using a blinker program one pin at a time produces no problems, however when I run a blinker program that cycles through all pins, pin 3 is set to constant high. My actual code is similar in function but more complex. This program below though gets the same error.

void setup()
{
  for (int c =2; c<12; c++){
    pinMode(c, OUTPUT);
  }
}

void loop()
{
  for (int c =2; c<12 ; c++){
     digitalWrite(c, HIGH);
     delay(100);
     digitalWrite(c, LOW);
     delay(100);
  }
}

Is this a sign my arduino died? My device had been working for weeks on my prior code with no problem (and no updates).

It is probably a dead chip. Try getting a new ATmega chip for the Arduino (easily found online for ~$5) and see if that fixes it.


formatting strings in Arduino for output I wander what is the best option for formatting strings in Arduino for output.
I mean what's a preferable way in the point of view of performance, memory usage  – things like that.
I see, people usually use direct Serial.print/println, like this:

  int x = 5;
  // 1st option
  Serial.print("x = ");
  Serial.println(x);

Or like this:

  // 2nd option
  Serial.println("x = " + String(x));

But what is wrong with, I believe, more traditional way of doing this:

  // 3rd optoin
  char strBuf[50];
  sprintf(strBuf, "x = %d", x);
  Serial.println(strBuf);

  // better one?

If you need the result in a single string then your 3rd option is the preferred way.

If you don't, then the first option of printing each part separately is the most efficient in terms of memory.

The second version, String concatenation, is the worst option in all respects and should be avoided at all costs.

I often use sprintf to a buffer if I need a specific format (for instance leading zeroes on a number).

If you want to avoid the extra code bloat of sprintf you can use various combinations of strcpy, strcat and itoa etc to build up a string into a memory buffer (if you really need to put it in a buffer).

Note that on an 8-bit Arduino sprintf has no float support - so you would still need to use dtostrf to format a float into a char buffer first, or print it directly.


How to use "+" character as a String Well I am trying to save phone number as a string. For ease of use I want to add "+" character programmatically. Like this:
String cepNo ="+" + "901234567";

But program gives this error.
exit status 1
invalid operands of types 'const char [2]' and 'const char [13]' to binary 'operator+'

How to add "+" beginning of the string.

You cannot add C strings (i.e. NUL-terminated arrays of char) with the
+ operator. It only works with String objects. You can, though, add
a String object and a C-string, because in this case the compiler
implicitly converts the C string into a String object:
String phone_number = "901234567";
phone_number = "+" + phone_number;

The last line is interpreted by the compiler as
phone_number = String("+") + phone_number;

That being said, I encourage you to try to avoid String objects if
possible. These use dynamic memory allocation which carries the risk of
heap fragmentation. The same thing can be achieved with plain C strings:
char phone_number[] = "901234567";
char full_phone_number[strlen(phone_number) + 2];
strcpy(full_phone_number, "+");
strcat(full_phone_number, phone_number);

Note the size of the second string: strlen(phone_number) + 2. You need
one extra char for the + sign, and another one for the NUL string
terminator.
Now, with C strings you can do better, and avoid copying: reserve enough
room in an array for the full number (“+” included), and then fill the
digits starting from the second slot in the char array. You can then
add the + sign later:
char phone_number[16];
strcpy(phone_number + 1, "901234567");
phone_number[0] = '+';

Although I personally would write the “+” sign and a NUL while
initializing the array:
char phone_number[16] = "+";
strcat(phone_number, "901234567");


Arduino circuit diagram help I'm new to the arduino and to EE in general. I've built the basic examples and a, now trying to get a deeper understanding of what the physics is doing. As such, I'd like some help in understanding the diagram here:

https://www.arduino.cc/en/Tutorial/Blink

Question 1:

Specifically,it seems that the flow is going from Pin 13 to Ground. Is the diagram using the conventional flow or the electron flow approach.

Specifically, is it the electrons flowing from Pin 13 to ground or does the diagram show protons flowing? It seems that its showing the electron flow as the diagram has the anode attached to the resistor so the electrons flow from the pin to the resistor to the positive end (anode) of the LED.

Question 2:
This is about bread boards, like one shown here:

https://www.google.com/search?q=arduino+breadboard&biw=1696&bih=988&tbm=isch&tbo=u&source=univ&sa=X&ved=0CFEQsARqFQoTCIjsw5WhkMgCFdWYiAodttcKIw#tbm=isch&q=breadboard&imgrc=KwnTrtjnYJdB1M%3A

1) Would I connect Pin 13 (or say the 5V pin) to the + (the red line). Then I would connect the blue line (the -) to the ground on the arduino? Do I need to connect the blue line?

2) Also, is it again the electron flow notation so that from Pin 13, the electrons flow to the + (red), then to one of the lettered columns and then to whatever component I have?

Thank you for your help! I realize these are basic questions but I want to go a little beyond building the examples and start trying things out myself. As such I want to make sure I'm getting the theory behind it right!

The thing to remember about electrons is they are a negative charge.  That means that the direction of current flow (positive charge) is opposite to the direction of flow of the actual electrons (negative charge). Picture it like those "compression jams" you get on the motorway (freeway) where cars that are travelling too close together have to slam their breaks on to avoid running into each other.  The one at the front slams its breaks on briefly then carries on. The one behind has to do the same, and so on and so forth.  You then get a wave effect travelling in the opposite direction to the direction of travel of cars as they slam their breaks on in turn.  The cars are moving forwards, but the compression jam is moving backwards.  Similar in a circuit - the electrons are moving forward, but the charge is moving backwards.

Another way to visualize it is as a bubble in a pipe of stationary water.  The bubble moves in one direction, but in order for it to do that the water has to flow past the bubble in the opposite direction.*

So the current flows out of pin 13 through the LED and to ground, but the electrons themselves are actually flowing from ground through the LED and in to pin 13 (where they eventually return back to ground through the power supply).

For how the IO pin works it's best to picture it as a pair of switches - one connected to Vcc and one connected to GND.  For instance, this is the LED wired up with the IO pin set to HIGH:

You can see that S1, being on, forms a circuit between the battery and the LED to allow the current to flow.

When the IO pin is set to LOW the circuit looks a bit like this:

You see that S1 is now turned off, and S2 is turned on.  the connection from that battery is now broken, and current can't flow.

But, you ask, what is the point of S2 here? It doesn't actually do anything.  No, not in that circuit it doesn't. But consider if you re-arrange the circuit to be like this:

Now it's S2 that is controlling the connection to the battery.  S1 is now the redundant switch.

This leads to some terminology.

When S1 is closed the IO pin is said to source current since it is pretty much connected directly to the positive power source.

When S2 is closed instead the IO pin is said to sink current since it is connected to ground, so current can "sink" down to ground through it.

As far as breadboards are concerned - they are just collections of metal strips that are used to join wires and component leads together in whatever way you need to.  There is no one part of it that is any different to any other, and there is nothing that says you must use this bit in a certain way, or that bit in another way.

Your typical breadboard has sprung metal clips that are arranged in this pattern:

You can use any collection of holes for any purpose you choose.

That said, normally the blue (or black) marked line of holes down each side is used for ground, and the red line of holes is used for power.  As both sides of the board are separate it is possible to use different voltages on each side, or the same voltage on both sides, etc.  That can be especially useful when you're working on a circuit that has, say, +3.3V and +5V in it.  Another common split usage is for a positive voltage on one side and a negative voltage on the other - common when working with op-amps.  Just remember which is which.

* This is a complete lie, but it's as close as you need to know at this point in your education. https://en.wikipedia.org/wiki/Lie-to-children


Arduino nano to esp8266 level shifting needed? I want to connect an Esp8266 Wifi module to an Arduino nano. I am wondering if I need to implement level-shifting for the Arduino TX line to Esp RX line?

I find different schema's on the net. Some with, some without level-shifting:

With:
http://community.blynk.cc/t/robot-with-esp8266-shield-and-arduino-nano/3316/8

Without:
Arduino Nano v3.0 with ESP8266

Some use a capacitor between GND and Esp CH_PD pin, others use a 10K resister between the 3.3V and the CH_PD pin (https://blogs.msdn.microsoft.com/abhinaba/2016/01/23/esp8266-wifi-with-arduino-uno-and-nano/)...

What is the most basic but required setup for a Arduino Nano and a Esp8266?
(I have Esp8266-12e modules)

Thanks!

The arduino nano v3's logic is 5v, and the ESP8266's logic is 3.3V, so you need to do level shifting between both.
Using a voltage divider drains more current (guess not an issue in this case) and it's ok only when going from 5V to 3.3V (when the signal must be shifted from 3.3V to 5V in the links you provide, it looks like it's based on that 3.3V is still considered "HIGH" on a TTL signal).

I personally prefer using a level shifter, it just complicates a bit the Bill Of Materials, but you won't have to debug the level shifting part.

And better than that, using an arduino mini pro @3.3v working directly at 3.3V gets rid of this hassle.


Serialize JSON as response to HTTP request I'd like my ESP8266 to provide some JSON endpoints. I want to use ArduinoJson for serialisation. While this works in general if I serialize into a String and return this String afterwards, I was wondering if there is really no way to do this without wasting so much memory. Shouldn't it be possible to do something like this? Any hints?

ESP8266WebServer server;
StaticJsonDocument<768> response;
response["night"] = _playback.isNight();
response["shuffle"] = _playback.isShuffle();
server.send_P(200, "application/json", NULL);
serializeJson(response, server.client());

(this gives the following error:)

no instance of overloaded function "serializeJson" matches the argument list -- argument types are: (ArduinoJson6141_0000010::StaticJsonDocument<768U>, WiFiServer::ClientType)

serializeJson() accepts a Print&, i.e, a reference to a class that implements the Print interface.

WiFiClient does implement the Print interface, but serializeJson() cannot make a reference to it because ESP8266WebServer::client() returns a temporary. Indeed, C++ forbids references to temporary variables, only const reference to temporaries are allowed.

To fix this compilation error, you must extract a variable:

WiFiClient client = server.client();
serializeJson(doc, client);

The way I see it, ESP8266WebServer::client() should return a WiFiClient& instead of a WiFiClient, just as HTTPClient::getStream() does. I opened issue #7075 about that.

Anyway, even it this fixes the compilation, I'm not sure it will work as you intend because ESP8266WebServer may not allow writing directly to the WiFiClient.


Add char at intervals in a String I'm trying to create a function that will take a String as an input, and at every 20 characters, it will instert "\n" so that the string doesn't go off the side of my screen (I'm using an oled with the SSD1306Ascii library).
This is my code so far, but when I run it nothing appears on the screen (I have another part of the code which passes the string to the funtion):
String message = "";
String newMessage = "";

void printMessage(String message) {
  oled.clear();
  if(message.length() > 20) {
    current = 20;
    while(current < message.length()) {
      newMessage = message.substring(current-20, current) + "\n";
      newMessage = newMessage + message.substring(current+1);
      current+20;
    }
    oled.println(newMessage);
  }
  else {
    oled.println(message);
  }
}

One issue with both your failed implementation and the previous answer
is that they do loads of dynamic allocations and copies. Every time you
use the String’s + or += operators you are allocating heap memory
for a brand new String, copying the original character data into the
newly allocated space, and eventually destroying the original Strings
when you don’t need them anymore.
The simplest way to avoid all these copies and allocations is to not
build the String you want. Instead, just write() the pieces one after
the other on the display. Here is a zero-copy, zero-dynamic allocation
solution:
void printMessage(const char *message) {
    size_t length = strlen(message);
    while (length > 20) {
        oled.write(message, 20);
        oled.write('\n');
        message += 20;  // point to the rest of the message
        length  -= 20;  // remaining length
    }
    oled.write(message);
}

Note that the method Print::write(const char *, size_t) is used here
to print a slice of the message without ever building it as a string in
memory.
On these memory-constrained devices it is always preferable to avoid
heap allocation, and thus String objects. However, if for whatever
reason you really need to print a String object, then you can use
the following overload to print it’s internal buffer without making any
extra copy:
void printMessage(const String &message) {
    printMessage(message.c_str());
}


What's wrong with my code? I was trying to do a LED display that turns on a LED at pin 13 that goes on then turns off after a delay then the next pin (which is pin 12 counting down) will turn on and then turn off.

I also put in a potentiometer that can change the delay to make it faster or slower.

Here's the code:

float pinOn = 13;
int outMin = 0;
int outMax = 13;
float delayNum = 1000;

void setup () {
  for (int i=outMin; i<=outMax; i++) {
  pinMode(i, OUTPUT); }
  Serial.begin(9600);
}

void loop () {
  // Reads Potentiometer -- sets delay relative to the Potentiometer input
  int sensorValue = analogRead(A0);
  delayNum = sensorValue;
  // Turns on the Pin designated by 'pinOn'
  digitalWrite(pinOn, HIGH);
  delay(delayNum);
  digitalWrite(pinOn, LOW);
  // Checks if 'pinOn' is 0 which then resets it back to 13 if not 0 then counts down
  if (pinOn = 0) {
    pinOn + 13;
  } else {
    pinOn - 1;
  }
}

All it does is turn on pin 13 for a moment then permanently turns on pin 1 and 0 and it gets stuck like that.

if (pinOn = 0) is doing an assignment (single =) not a comparison (double ==), so pinOn is begin set to 0 each time through the loop. The result of an assignment is the value being assigned. So it's the same as if ( 0 ), which is false.

Now, on to the two branches. pinOn + 13 is a statement and the result is not being assigned to anything. You need an equals sign somewhere:

if (pinOn == 0) { // == means "is equal to"
  pinOn += 13; // same as pinOn = pinOn + 13
}
else {
  pinOn -= 1;
}


Protecting your computer from stupid (arduino) mistakes I recently ran way to much voltage through my Arduino and back into my computer via the USB connection. I'm looking for a USB hub with a fuse or some sort of protection to protect my laptop from these types of mistakes.  Any suggestions as to products that would serve this function or other precautions I might take?

Both the arduino and a USB port do have some protection against wrong connections and such. The arduino has a diode to prevent wrong polarity to reach your power supply, it also have a resetable fuse (the kinda big, often green SMD part close by your USB connection on your Arduino) that should protect your USB port pretty good from its side of the cable. Your USB port also have some good protections going on as far as i know, so basically it should be hard to break a USB port by accident.

That was the theoretical part, In real life things aren't always what they claim to be, so I use a cheap powered USB hub, that i always use as a first line of defense.


Can we control other servos with common servo code Arduino I am trying to control MG996R using code for a typical servo (SG90)
I used an external power supply, 5V,2A
I connected the servo signal line to Arduino slot 7,
servo positive to external power supply positive,
servo ground to external power supply ground,
while leaving the Arduino power supply and ground unconnected.
I tried the below code.
it works for SG90, while MG996R is not moving at all.

#include <Servo.h>
Servo myservo;

void setup()
{
  myservo.attach(7);  //pin 7 is the one control servo

}

void loop()
{

  for (int pos=0; pos<=60; pos++)
  {
    myservo.write(pos);
    delay(15);
  }

}

Is it because the different servos need different code?

They work with same control signal, so the same code should work for both of them
You need make sure the ground of servo is both connected with the Arduino ground and the power supply ground (power supply ground for power supply positive, Arduino ground for the signal line)
I think SG90 worked even not connecting the Arduino ground is because the difference in design.
But you should always connect Servo ground to the Arduino ground.


Modifying serial message for Adafruit NFC/RFID card Using an Uno configured with an Adafruit RFID-NFC shield to send the UID values to a desktop game I am building.

Works fine. However, in addition to just the UID, I need to send 1 additional value, lets call it 'game choice'. This can be one of 3 values. This is just the relevant code. Can any experts suggest how I might modify the following to send this additional value?

/**************************************************************************/
#include <Wire.h>
#include <Adafruit_NFCShield_I2C.h>

#define IRQ   (2)
#define RESET (3)  // Not connected by default on the NFC Shield

Adafruit_NFCShield_I2C nfc(IRQ, RESET);

void setup(void) {
  Serial.begin(115200);
  Serial.println("Hello!");

  nfc.begin();

  uint32_t versiondata = nfc.getFirmwareVersion();
  if (! versiondata) {
    Serial.print("Didn't find PN53x board");
    while (1); // halt
  }
  // Got ok data, print it out!
  Serial.print("Found chip PN5"); Serial.println((versiondata>>24) & 0xFF, HEX);
  Serial.print("Firmware ver. "); Serial.print((versiondata>>16) & 0xFF, DEC);
  Serial.print('.'); Serial.println((versiondata>>8) & 0xFF, DEC);

  // configure board to read RFID tags
  nfc.SAMConfig();

  Serial.println("init");
}
void loop(void) {
  uint8_t success;
  uint8_t uid[] = { 0, 0, 0, 0, 0, 0, 0 };  // Buffer to store the returned UID
  uint8_t uidLength;                        // Length of the UID (4 or 7 bytes depending on ISO14443A card type)
  int nfcDEC;
  success = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, &uidLength);

  if (success) {

   nfc.PrintHex(uid, uidLength );
}
}

had to simply modify PrintHex in
Adafruit_NFCShield_I2C.h

to accept an additional argument


Can't communicate with SIM800 module I am using Arduino Uno R3 and a SIM800L (voltage regulator built in). My initial setup included a 10kΩ resistor soldered between the lower end of the RX and GND pins on the SIM800L, and a 4.6kΩ resistor soldered on the jumper connecting SIM800L's RX and Arduino's declared TX (pin 7). SIM800L has its own power supply (5v-2A). This is a setup I have used previously on two different SIM800L modules, and everything worked fine without any (visible) problems.

Baud rate is set to 9600 in Arduino IDE, PC port (via Device manager), and the module, through the sketch.

After loading the sketch (first one) shown on this site, the SIM800L connects to the GSM network (I can tell by the delay between blinks), but the module does not respond to AT commands send via serial monitor.

The sketch

#include <SoftwareSerial.h>

//SIM800 TX is connected to Arduino D8
#define SIM800_TX_PIN 8

//SIM800 RX is connected to Arduino D7
#define SIM800_RX_PIN 7

//Create software serial object to communicate with SIM800
SoftwareSerial serialSIM800(SIM800_TX_PIN,SIM800_RX_PIN);

void setup() {
  //Begin serial comunication with Arduino and Arduino IDE (Serial Monitor)
  Serial.begin(9600);
  while(!Serial);

  //Being serial communication witj Arduino and SIM800
  serialSIM800.begin(9600);
  delay(1000);
}

void loop() {
  //Read SIM800 output (if available) and print it in Arduino IDE Serial Monitor
  if(serialSIM800.available()){
    Serial.write(serialSIM800.read());
  }
  //Read Arduino IDE Serial Monitor inputs (if available) and send them to SIM800
  if(Serial.available()){
    serialSIM800.write(Serial.read());
  }
}

Things tried

Thinking that the resistors might be causing this, I removed all of them, and made a clean connection with Arduino. And the problem persisted.

I tried resetting the module, by passing the ATW command into a sketch:

serialSIM800.write("ATW\r\n");

and that also gave no results. Further testing with:

if(!serialSIM800.available()) {
    Serial.println("Not working");
}

indicated where the problem might be.

I have also tried changing the baud rate to 48000, 57600, and 115200, but that did not solve my problem.

The question

Am I right in assuming that a reset to factory settings could solve my problem? If so, how can I reset the module, without the AT commands? If resetting would do me no good, what else could I try?

This is widely happen problem - serial communication with SIM800L stopped working.
You can do reset, but in my case it didn't help: on powered SIM800L module shortcut "RST" pin with the ground for half of second - unit should reset and restart. I think it's defective architecture/firmware, but unfortunately SIMCOM dropped support for this model, so best advise is to avoid SIMCOM until they study how to make quality products.


Will a transistor always reduce the voltage? I have an NPN transistor that's connected over a 12V adapter. I have tried using a potentiometer to change the resistance of the incomming current. Even if i take the resistance down to 0, I end up with at most 11 Volts when measuring over the magnet.

I have measure the energy without the transistor, in that case it's 12V. Is this expected behaviour of a transistor or is something wrong?

Yes, it is, as both VCE(sat) and the "Collector-Emitter Saturation Voltage vs Collector Current" chart in the datasheet tells you.


Continuous voltage on IO Pins while 5V is not Connected? i have a small project where i just sucessfully destroyed my frist of 5 Digisparks (Attiny85).

In the Picture you see the Cirucit. I have 2 Liion cells connected in series to get high enough voltage to step it down to constant 5V. To these 5V some Neopixels and a Digispark controller are connected which will set the color for the Neopixels. A0 and A1 measure the Voltage of the Cells to signal the user if the Voltage is to low so it can manually be switched of.
While prototyping it i didnt have the 10k resistors in there.
Now what happend: While connecting the cells after each other the Controllers LEDs already lit up with the Frist cell. I guess it was powered trough the A0 pin (again i didnt have the 10k resistor in there),  so i guess the internal IO Protection diodes conductet the voltage trough and this way the controller got damanged. Since this happend it wont turn on Anymore.
The problem: since i have really small space i cant use a multiple pole switch to also remove the voltage from the IO pins and therefore i will always have voltage von A0 and A1 while there is no 5V Supplyvoltage. I would guess that the Series resistance on the pin would be enough to Limit the current trough them and this way protect the controller from damange. But i dont really have experience with that and hope that you guys can give me some hints what could also be a problem or what could help :) I really dont want to destroy a second one xD
Thanks in advance and have a nice day :)

For this I would recommend isolating the power from the batteries with P-channel MOSFETs and only switching them on when you want to sample the voltage. This means that there is no power consumption at all (aside from an absolutely minuscule leakage current) when turned off.
The whole setup would require 4 MOSFETs - two P-channel and two N-channel. They don't need to be big, since the currents involved are very small, but they do need to have "logic level" thresholds, ideally < 1.5V (-1.5V for the P-channel).
The basic circuit looks like this:

simulate this circuit – Schematic created using CircuitLab
The circuit is made up of two identical segments - M1+M3 and M2+M4.  The operation is fairly straightforward:

M1 (M2) is kept in the OFF state by R1 (R2) pulling the gate up to source.
M3 (M4) can pull the gate of M1 (M2) LOW turning it on and allowing current to flow
Any GPIO pin (D7 in this example) can control both M3 and M4 together
R5 keeps M3 (M4) off when there is no power - otherwise it floats.
R3/R4 are your existing voltage divider.

The purpose of M3 and M4 is to both turn the GPIO (D7) into "open drain" so that it's either pulling down or floating high (rather than driving high at 5V) and to isolate the two pullup gate voltages. The same effect could be achieved by two diodes and one MOSFET but it's simpler to just use two MOSFETs and not have to get diodes as well.


Receive data from multiple wireless sensors simultaneously I want to receive data from multiple (2/3) wireless sensors at the 512 Hz data rate simultaneously at a single receiver (bluetooth or any other wireless standard). Is it possible with one receiver or I need  multiple receivers?

I am novice to wireless communication please guide me to any available resources.
Thank you.

It is possible to do this with Zigbee. The API mode in the Xbee modules enables this.

Unlike the AT mode in Zigbee the API mode enables you to distinguish between the packets that you receive from different slaves.

In the API mode, you send each data packet with as a frame with a header which contains start delimiter byte, most significant byte (which tells where the start byte is at), least significant byte (which tells the end of the byte), an API identifier, the data that you want to send and a checksum byte.

This link provides a nice tutorial which shows how to setup Xbees on API mode with an Arduino and Python:
http://serdmanczyk.github.io/XBeeAPI-PythonArduino-Tutorial/

I hope this helps.


Bootloader and Boards Definition for Atmega2560V-8AU at 8 MHz / 3.3v I am working on a home made project,where i am using Atmega2560V-8AU (note the suffix, this part has an 8 MHz maximum clock rate) as my main controller, supplying 3.3V to this chip.

I want this controller to work exactly same as standard Atmega2560-16AU like on Arduino Mega(perhaps at a slower baud rate on account of the slower clock)

Does there already exist a suitable bootloader image and board definition for an ATmega2560 operating from an 8 MHz crystal?

If not, what changes would need to be made to the usual 16 MHz bootloader and boards definition to support 8 MHz operation, both for the bootloader and for correct time functions and serial buad rates in sketches?

I have used megacore bootloaders, and it solved the problem


is it possible to write two threads in arduino & switch between data & AT command mode dynamically? I need to recieve data from a android phone and also estimate distance of phone from the HC 05 module , So i want to write two threads or functions. In one part i want recieve data from android phone store it in a variable and in other enter AT command mode to see RSSI of the phone.

You can switch between command and "online" modes, but you cannot use both at once. While in command mode you can't be receiving data, and while in online mode you can't be sending commands.

You would have to periodically switch between the two in your program at a time when you know you won't be receiving data (or you don't mind losing that bit of data).

And no, the Arduino doesn't have the concept of threads. There are a number of libraries that do emulate threads to a certain extent, but they are (usually) cooperative multi-tasking (one "thread" has to manually "yield" to another) and as such are pretty pointless, since you can get the same effect with a decent finite state machine.


How to rotate two or more steppers simultaneously by giving ARRAY of angles? The following is the code that I am trying but the problem is steppers rotate one after each other. However, I want to rotate steppers simultaneously.
This code for two stepper motors.

int pulse=3;

int direc=4;

int pulse1=5;

int direc1=6;

int i,j,k;

float angle[5][3]={{360,360,3},{7,8,9},{11,12,13},{14,15,16},{17,18,19}};

float steps;

void motor1(){

  for(k = 0; k<=4; k++){

    Serial.println(angle[k][0]);

    steps = (1600*angle[k][0])/360;

    Serial.println(steps);

    for(j = 0; j<=steps;j++){

      digitalWrite(3,HIGH);

      delayMicroseconds(100);

      digitalWrite(3,LOW);

      delayMicroseconds(100);
        }

}

}

void motor2(){

  for(k = 0; k<=4; k++){

    Serial.println(angle[k][1]);

    steps = (1600*angle[k][1])/360;

    Serial.println(steps);

    for(j = 0; j<=steps;j++){

      digitalWrite(5,HIGH);

      delayMicroseconds(100);

      digitalWrite(5,LOW);

      delayMicroseconds(100);

        }

}

}

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

  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT);
}

void loop(){
    motor1();

    motor2();

   //while(1);
}

(Half a year ago, but what the hey...)

Your motor1() and motor2() are currently written as:

do until done:
  take a step
  wait
end

, so yeah, one finishes before the next one even starts.

Each motor function needs to do:

if motor's current-position is not the final position,
   if it is time to take a step,
      take a step
      calc when to take another step
      calc motor's new current-position
   end
end

Now call your motor functions as frequently as possible. Notice that either if test can cause the function to return without doing anything - that is intentional.

This is non-blocking programming - coding in such a way that nothing keeps control while waiting for something to happen (clock ticks, in this case), it just does something, or does nothing, right now, if there is or is not something to do right now, but it does release the processor (the function returns immediately) whether it did something or not.

I call these functions "maybe-do" functions:

maybe step a motor (if, and only if, a certain interval has passed, step the motor);
maybe light an LED (if, and only if, the button is being pressed and it wasn't pressed the last time we looked, turn on the LED;
maybe read the terminal keyboard (if there is at least one character in the Serial input buffer, collect a character).

Then your loop() function should do nothing but call each maybe-do function, in sequence, as fast as possible. And it follows from the above that your maybe-do functions need to execute as quickly as possible and do no more than is necessary to (1) decide whether to act, and if so, (2) to carry out its action, and (3) in either case, return immediately.

And - Bang-Boom! - right there is a half-semester course in block-free programming without interrupts!


Arduino Due power supply I have an Arduino Due.  It communicate to the computer with the native usb port. It is also powered by the native port. Anyway, the connected sensors are pretty sensitive to the current, thus I would like to use a power supply (as a portable smartphone charger) in order to provide the current at the Arduino.

How can I say to the Arduino to get the current from another 'port' (e.g. the serial programming) and use the native port only for the communications?

You can't really fiddle with the power circuitry of the Due. If external sensors need more power than the due can provide through its internal 5V connection, whatever you choose that to be (dictated by the USB connection used) then you will either have to use a higher voltage to feed the barrel jack, or better, power the sensors separately to the Due. Just remember to connect the grounds.


Relay doing opposite to digital pin I have a Arduino UNO with a Ethernet shield which hosts a basic HTML page with a button on it which controls a Relay module.

I'm trying to connect to a computer's power button so I can turn it on remotely.

I have found out that the relay basically does the opposite to the digital pin's output

Normally open Relay
HIGH = Open
LOW = Closed

I connected it through a NOT Gate made using a NPN transistor and it works perfectly how I wanted it.

Now to the question... Is there a way to write the code to make the digital pin = HIGH straight away and fast enough to not allow the relay to close the circuit and accidentally turn the computer on/off when the Arduino restarts, so I don't have to use a NOT Gate.

The relay module you have is this one from SainSmart:

http://www.sainsmart.com/arduino/arduino-components/relays/sainsmart-2-channel-5v-relay-module-for-arduino-raspberry-pi.html

The schematic is like this:

As you can see you connect VCC to +5V and IN2 to your IO pin.  Setting the IO to LOW will then turn on the LED and the optocoupler together.

But that's not the only way you can connect it up.

Connect VCC to the IO pin and IN2 to GND instead.  Then you set your output HIGH to turn it on.

The arrangement shown in the schematic is commonly done because some MCUs are able to sink more current than they can source thorugh an IO pin.  That is not the case with an Arduino which has symmetric IO pins that can sink and source the same amount of current.


Is there a way to add external RAM (let's say 100 MB or 200 MB) in this audio buffer mixing context? I'm coding a music sampler device: for fast playback / minimal latency (only a few milliseconds), it's better to have all audio .wav samples we want to use in RAM, so that when some of them are  played, the data arrays are immediately accessible. That's what I did for a Raspberry Pi project called SamplerBox. It was possible because RPi had 1 GB RAM.

Note: When using SDcard reading, and playing many notes at the same time (imagine a pianist playing a big chord), it's usually not good in terms of latency.

Now I'm thinking about porting this project to Arduino: in which extent can we add external RAM to an ATmega? Or if not "RAM", some volatile memory (let's call it "RAM2") that would be 10 times faster than reading an SD card.

What I'd like to achieve:

load 200 MB of audio samples into the "RAM2"
Max polyphony allowed = 100, so at a given time, all audio buffers that have to be mixed can be copied from "RAM2" to the "real" RAM of the microcontroller, and the mixing will be done with the (maximum 100 of them) buffers in the real RAM

There are SRAM ICs / boards, however, don't expect 100 MB, more like 1 MB (with the pin numbers and connectivity / protocols that an Arduino offers).

With Flash you can get much further, but it can only be written a number of times; not sure if that suits your requirements.

Beyond that, I'm afraid the real problem is in the processing speed. Mixing 100 samples with 48 KHz stero would mean (48000 * 2) = 96 KSamples/s. Since the Arduino is only 16 MHz you have just 16e6/96e3 = 166 clock cycles to mix all those 100 samples. Probably way too less.

Update

Winbond is a brand that is supported by Arduino libraries and the biggest supported IC is e.g. W25Q128FVSSIG, which is 128 Mbit, thus 8 MB. For 200 MB you need 25 of them which is quite a lot, and not sure if there will be issues using so many (let alone the cost). For this you do not need a file system, however you need to write it per page (if you want to do it efficiently). Which should be ok, since the SD card also is read per page (maybe not the same page size though).
However, you still have to copy the Flash memory into SRAM to be able to process it, so it's not the same as SRAM. Getting 200 MB SRAM will be very costly.


Trying a crude water level sensor first of all, Im from Cuba, that means I may have some problems to find parts...

I have a little system to measure the water level in my house water tank. The system is pretty rough: a proximity sensor HC-SR04 well fixed in the top of the tank, some long wires to an ArduinoNano, and a LCD screen where I display information as: water level in liters and in %.

The problem is the proximity sensor HC-SR04 seems to be broken now, not work at all and I was thinking in replace it by raw cables

Something like in the image below, but maybe with more steps:

So... My questions are:

-Is this posible? I just test it with a glass of water and two short wires and it work, but sometimes it throw me some falses-positives... It may be my code: just light on a led if digitalpin X is high when I put two wires in the water (1 wire to arduino 5V pin and the other to the digitalpin I wanna check if is high), and it do it, but when I pull out the wires the led stay on for more than a few seconds.

-If it is posible, how long can be the wire? Is 10m ok?

Thanks

As others have said, you need to make sure you have pull-up or pull-down resistors on all digital inputs so their value doesn't "float" (fluctuate between high and low.)

Given that water tanks and wells tend to be strongly earth grounded, I would suggest some changes:

Change the common wire to a ground, not +5V

Change all of your other pins to analog inputs. Connect them to high ohm pull-up resistors (say 10kΩ). They will read a full 5V when their ends are not in water. When the water rises and the ends dip into the water, their voltages will drop. Use analog readings to detect those voltage drops.

You could also use something like graphite a pair of graphite rods in the water, and a voltage divider circuit. As the water level rises, the current would travel through less graphite, and the resistance would drop. I don't know if that would give you enough top-to-bottom measuring distance.