ESP8266 - ESP01S with relay. Toggling the relay with http (GPIO0) and GPIO2 at the same time I have an ESP8266 module with a relay like this: https://aliexpress.com/item/4000348370586.html.
I have been able to control the module, I can deactivate and activate the relay by means of an http request, with the following code.
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>

#ifndef STASSID
#define STASSID "wifi_name"
#define STAPSK  "wifi_password"
#endif

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

ESP8266WebServer server(80);

IPAddress ip(192, 168, 0, 101); //ESP static ip
IPAddress gateway(192, 168, 0, 1);   //IP Address of your WiFi Router (Gateway)
IPAddress subnet(255, 255, 255, 0);  //Subnet mask
IPAddress dns(8, 8, 8, 8);  //DNS
const char* deviceName = "ligth101";

const int relayPin = 0;

void handleOn() {
    digitalWrite(relayPin, LOW);
    setCrossOrigin();
    server.send(200, "text/plain", "Ligth on");
}

void handleOff() {
    digitalWrite(relayPin, HIGH);
    setCrossOrigin();
    server.send(200, "text/plain", "Ligth off");
}

void handlePing() {
    setCrossOrigin();
    server.send(200, "text/plain", "ligth");
}

void configPin(){
    pinMode(relayPin, OUTPUT);
    digitalWrite(relayPin, HIGH);
}

void configWifi(){
    WiFi.setAutoConnect(false);
    WiFi.disconnect();
    WiFi.hostname(deviceName);
    WiFi.config(ip, subnet, gateway, dns);
    WiFi.begin(ssid, password);
    while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    }
}

void setCrossOrigin(){
    server.sendHeader(F("Access-Control-Allow-Origin"), F("*"));
    server.sendHeader(F("Access-Control-Max-Age"), F("600"));
    server.sendHeader(F("Access-Control-Allow-Methods"), F("PUT,POST,GET,OPTIONS"));
    server.sendHeader(F("Access-Control-Allow-Headers"), F("*"));
}

void sendCrossOriginHeader(){
    setCrossOrigin();
    server.send(204);
}

void configServerPaths(){
    server.on(F("/ping"), HTTP_OPTIONS, sendCrossOriginHeader);
    server.on(F("/ping"), HTTP_GET, handlePing);

    server.on(F("/on"), HTTP_OPTIONS, sendCrossOriginHeader);
    server.on(F("/on"), HTTP_GET, handleOn);

    server.on(F("/off"), HTTP_OPTIONS, sendCrossOriginHeader);
    server.on(F("/off"), HTTP_GET, handleOff);

    server.begin();
}

void setup() {
    configPin();
    configWifi();
    configServerPaths();
}

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

Now, I want to use the GPIO2 pin to also turn the relay on and off. The desired behavior is to change the state of the relay regardless of whether it comes from the button or from an http request.
I have tried the following modifications to the code:

const int buttonPin = 2;
int buttonState = 0;

void configPin(){
    ...
    digitalWrite(buttonPin, LOW);
}

void handleButton(){
    buttonState=digitalRead(buttonPin);
    if(buttonState == HIGH) {
        digitalWrite( relayPin, !digitalRead(relayPin) );
        delay(1000);
    }
}

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

With these modifications to the code, I have tested the following two modifications to the hardware:

Placing a switch between ground and GPIO2. As a result of this, each time I activate the push-button, the relay remains intermittent, going from one state to the other infinitely.
Placing a switch between ground and GPIO2, but adding a resistor between the switch and the GPIO2 pin, but this also does not work.

Is there a way to deactivate / activate the relay using GPIO2 with a push button and via http as well?
Thanks!

Contrary to esp-01, on the esp-01S io 0 and io 2 pins have a pull-up resistor.
Wire a button between io 2 and ground and you will read LOW if the button is pushed.
Use a state variable for the state of the relay, don't read back the pin (does it even work to read the state of an output pin with digitalRead on esp8266?).


writting to buffer from serial input Can some one explain this behaviour please, i have the following code

  byte buffer[512];
  byte block;
  byte len;

  Serial.setTimeout(60000L) ;     // wait until 20 seconds for input from serial
  // Ask personal data: Family name
  Serial.println(F("Type text followed by #"));
  len = Serial.readBytesUntil('#', (char *) buffer, 500) ; // read from serial
  Serial.print(len);
  for (byte i = len; i < 250; i++) buffer[i] = '#';     // pad with #
  Serial.print(len);

This works but if i change the "for" line to any thing higer then 250 it stops working and there is a "buffer out of memory condition)

My question is why can't the for loop say the below as the buffer size is 512?

for (byte i = len; i < 512; i++) buffer[i] = '#';

Am i right in thinking it has something to do with  (Char *), i did copy this code from the example ardunio code and was jsut trying to incress the lenth of input it accpeted.

A byte can only contain values from 0 to 255 (including).

So my guess it works for values until 255.

You should use a different type, e.g. unsigned int or unsigned short.

for (unsigned short i = len; i < 250; i++) buffer[i] = '#';     // pad with #

Also, I advise to use a constant or define for the buffer size, now you have 3 values (512, 500 and 250 in the loop, I assume they should be based on the same value).

About the char*: Looking at StreamReadBytesUntil, it seems that the parameter wants a char* instead of a byte* (which is more or less the same), but it's better to cast to show the parameter is of type char* since that is high likely the exact type (but the official Arduino documentation does not show the parameter types sadly).


Measure total microcontroller current? So I have a Duemilanove board and am utilizing 7 output pins, I power a Pixy camera and pan/tilt servos from the ICSP header, i also power an HC-SR04 sonar snsor directly from the board.
Of those 7 output pins, 4 are PWMs for the motors (don't ask why), 3 are for servo control (tower pro mg-995)
when I try to output these 7 pins simultaneously things don't work, i get "components at a time" behavior. Like servos turn first, then the motors spin (servos stopped).
Initially we thought it must be a power supply problem (8 1.2v NiMh bat series) which powers the l298n h bridges (two of them) and also powers the board and servos. But now im starting to fear that it's the board itself and that it can't handle simultaneous outputs.
I've read from here (method #10) that taxing the board more than 200mA is a problem. But what exactly happens if you do just that? And is my case exactly like this one? If so, how to fix it?

Edit +

Here's how the circuit looks.

Edit:
Yes i do think there is a need for decoupling capacitors but im not sure where to put them. They dont seem to work. The bounty goes to the best answer on the proper decoupling of this circuit.
Edit:
Here's some images on the Pixy camera

Edit:
Actually from the original problem I noted when I posted this question, things don't work as expected. WHen the big servos move, the pan/tilt camera don't move when they are supposed to, or the motors briefly stop. I'm wondering if is also an Arduino idiosyncrasy because when I don't run the servo.attach(servo_pin)  code everything works fine.

My experience of high power draw from an Arduino is that it endlessly re-boots so maybe not the issue for you.

The Servo library and PWM pins are probably sharing the same timer therefore motors stop while servos are running.

You could try a different Servo library.

This article is useful to understand the timer/pwm/pin relationships


Sending Large Packets and Reassembling over Serial I'm trying to send info of about 30-40kB over the Serial ports on an Arduino Due. But I'm running into a few problems.
First, before we get into the actual transfer over the Serial, I want to try storing 30000 Bytes into a char * array.

Also as a disclaimer, I've modified the SAM library's RingBuffer.h SERIAL_BUFFER_SIZE to 256 from 128.

void setup() {
  Serial.begin(115200);
int i,j=0, cksum=0;
int *test;
test = (int*)calloc(1,30000);
Serial.println("Starting...\n");

for(i=0;i<30000;i++){
  test[i]=i;
  cksum +=j;
  j++;
  if(j>255){j=0;}
}
Serial.print("cksum is: ");
Serial.println(cksum);
cksum = 0;
for(i=0;i<30000;i++){
  if(i<300){ //only print out the first 300 characters, otherwise it's hard to see anything
    Serial.print("[");
    Serial.print(test[i],HEX);
    Serial.print("]");
  }
  cksum+=(int)test[i];
}
Serial.print("\nNow cksum is: ");
Serial.println(cksum);
}

Obviously, since *test is a byte array, I'm only storing int8 into there - so from 0-255.
That means that the data received in *test increments from test[255]= 255 to test[256] = 0. The way around this would be to use some kind of itoa function to write out multiple bytes that represent the numbers being written (causing an overflow because it would no longer be an array for 30000 Bytes). But for these purposes is it ok to simply realize that this is happening and just write the bytes to the array.

Ok, so for part two, I want to do the same thing, but by writing to Serial2 from Serial3 and receiving all of the bytes:

void setup() {
  Serial.begin(115200);
  Serial2.begin(115200);
  Serial3.begin(115200);
int i,j=0;
double cksum=0;
char *buf;
Serial.println("Starting...\n");
buf = (char*)calloc(1,30000);

Serial.println("Writing to Serial3");
  for(i=0;i<30000;i++){
    Serial3.write((byte)i);
    cksum+=j;
    j++;
    if(j>255){j=0;}
  }
 Serial.println(cksum);
 Serial.println("Reading from Serial2");
 Serial2.readBytes(buf,30000);
 cksum = 0;
  Serial.print("Buf is: ");
  for(i=0;i<30000;i++){
    if(i<300){ //only print out the first 300 characters
      Serial.print("[");
      Serial.print(buf[i],HEX);
      Serial.print("]");
    }
    if(buf[i] != j){
      Serial.print("\nMismatch at i = ");
      Serial.print(i);
      Serial.print("\nBuf is: ");
      Serial.print(buf[i-1],HEX);
      Serial.print(",");
      Serial.println(buf[i],HEX);
    }
    cksum+=buf[i];
    j++;
    if(j>255){j=0;}
  }
  Serial.println("\n\nEnd");
  Serial.println(cksum);

}

What happens here is that I get a mismatch at byte 255. The increment (in hex) goes:

[254] = FE
[255] = 30
[256] = 31

But it should read:

[254] = FE
[255] = FF
[256] = 0

After reading some other forums, and the fine AVR Arduino post here, I feel like something is happening on the Serial interrupt level that I am not aware of. All of the data is properly transferred to the Serial and I am able to see all of the bytes in the correct order coming out of TX and into RX on my logic analyzer.
I've also experimented with different baud rates, but see no reason why a 84Mhz chip would not be able to handle a baud rate of 115200.

Has anyone else run into this? How do you handle these transfers of continuous data that is larger than the buffer? Is the only option here to run readBytes in SERIAL_BUFFER_SIZE increments until Serial is no longer available? Or can I still salvage using readBytes all in one go as I am trying to do?

I know this question has been asked in certain forms in other threads like here and here but they do not solve this particular problem I am experiencing, most likely because they are not Due specific.

Let me dissect your program and show you precisely what is going on and why your approach is completely wrong:

Your first step is to throw 30,000 bytes at the serial port. Those go via the TX ringbuffer, which is (as you have changed it for some reason) 256 bytes:

buf = (char*)calloc(1,30000);

Serial.println("Writing to Serial3");
  for(i=0;i<30000;i++){
    Serial3.write((byte)i);
    cksum+=j;
    j++;
    if(j>255){j=0;}
  }

At this point 29744 bytes have left the hardware UART. 256 are still sat in the TX ringbuffer being sent out by the TX interrupt routine.  The first 256 bytes that were sent out were picked up by the RX interrupt routine and stored in the RX ringbuffer. The next 29488 bytes were discarded (they are now all over the carpet with your marbles).

 Serial.println(cksum);
 Serial.println("Reading from Serial2");

Now you try and read 30,000 bytes from the 256 byte RX ringbuffer. While you are doing that the remaining 256 bytes in the TX ringbuffer are being slowly sent out. You are now making some room in that RX ringbuffer since you are removing bytes from it, so some of the remaining 256 received bytes can now be stored in it. The first one of those happens to be 0x30.

 Serial2.readBytes(buf,30000);

Now you go and print out your array, which has only a tiny fraction of the 30,000 bytes you sent in it.

 cksum = 0;
  Serial.print("Buf is: ");
  for(i=0;i<30000;i++){
    if(i<300){ //only print out the first 300 characters
      Serial.print("[");
      Serial.print(buf[i],HEX);
      Serial.print("]");
    }
    if(buf[i] != j){
      Serial.print("\nMismatch at i = ");
      Serial.print(i);
      Serial.print("\nBuf is: ");
      Serial.print(buf[i-1],HEX);
      Serial.print(",");
      Serial.println(buf[i],HEX);
    }
    cksum+=buf[i];
    j++;
    if(j>255){j=0;}
  }
  Serial.println("\n\nEnd");
  Serial.println(cksum);

}

The simple fact is, you are transmitting, en-masse, far more bytes than the Arduino's RX ringbuffer can hold. In order to receive more than the 256 bytes of the ringbuffer you have to read the bytes from that ringbuffer to make room for more to arrive. And since you are the one that is transmitting that means you have to do your receiving at the same time as the transmitting.

The only possible way that your arrangement of program could work would be if you increased the RX ringbuffer to greater than 30,000 bytes so it can store all the received bytes as you transmit them for you to then, afterwards, copy the contents of that ringbuffer into your own buffer.


Can you drive a stepper motor without the L293D Can you drive a stepper motor without L293D.

Don't awnser without giving explanations or saying it will be cheaper to buy the L293D.

Thanks

Depending on the type of stepper motor the answer can be "Yes" or "No".

There are two types of stepper motor: Unipolar and Bipolar.  Bipolar motors typically have 4 wires and require a H-bridge to drive them.

The L239D is a popular (and cheap), though inefficient, H-bridge that is commonly used. But it is possible to build your own H-bridge from discrete components. There are a lot of caveats and pitfalls when building your own H-bridge though, so people generally don't unless they have a specific requirement that isn't addressed by an integrated one. There are plenty of schematics and descriptions of operation online if you want to learn more about H-bridges.

There are also dedicated bipolar stepper drivers which are easier to work with: you just set the direction and give it a pulse to step in that direction. Much easier to program with, but can be more expensive. However these do tend to be more modern MOSFET based components which are far more efficient and dissipate less heat (or can handle more powerful motors in a similar size package).

Unipolar stepper motors, on the other hand, have more wires (typically 6) and are much simpler to drive. All you need for these is a transistor per coil (typically 4 coils connected as pairs) and you just need to activate them in the right sequence.

The ULN2003 is a popular integrated chip for driving unipolar stepper motors. It's just a bunch of transistors in a single package that is easier to wire up than discrete transistors, though there is no reason why you couldn't do it just with 4 discrete transistors. It's just simpler and tidier to use a single chip.

There are plenty of demonstrations and tutorials online describing driving a unipolar stepper motor with the ULN2003.


RGBs, photoresistors, and delays I am having a little trouble with a program of mine. My circuit consists of (mainly) an arduino UNO, two RGB LEDs, and a photoresistor. My current code(programmed in c#) operates the hardware as so: When the lights in the room are on, the two LEDs alternate blue/off once per second in a loop. When the lights are off, or the photoresistor is not sensing any light, both LEDs turn on, and stay on, red.
My code:

int prPin = A0;

void setup()
{
  pinMode(5,OUTPUT);
  pinMode(6,OUTPUT);
  pinMode(7,OUTPUT);
  pinMode(8,OUTPUT);
  pinMode(9,OUTPUT);
  pinMode(10,OUTPUT);
  pinMode(prPin,INPUT);
  Serial.begin(9600);
}

void loop()
{
  int prVal = analogRead(prPin);
  Serial.write(prVal);
    if(prVal>450)
    {
      digitalWrite(5,HIGH);
      digitalWrite(6,HIGH);
      digitalWrite(7,HIGH);
      digitalWrite(8,LOW);
      digitalWrite(9,HIGH);
      digitalWrite(10,HIGH);
      delay(1000);
      digitalWrite(5,LOW);
      digitalWrite(6,HIGH);
      digitalWrite(7,HIGH);
      digitalWrite(8,HIGH);
      digitalWrite(9,HIGH);
      digitalWrite(10,HIGH);
      delay(1000);
    }
    else
    {
      digitalWrite(5,HIGH);
      digitalWrite(6,HIGH);
      digitalWrite(7,LOW);
      digitalWrite(8,HIGH);
      digitalWrite(9,HIGH);
      digitalWrite(10,LOW);
      delay(10);
    }
}

The problem I am having is when the lights turn off, the LEDs will not operate according to the "else" statement/loop until it finishes going through the "if" statement/loop.
Any suggestions or answers are appreciated. I'm an open book, so I'll take anything you guys give me.

Instead of the two delays of one second, have the program check if the current time is an even or odd number of seconds.

int prPin = A0;

void setup()
{
  pinMode(5,OUTPUT);
  pinMode(6,OUTPUT);
  pinMode(7,OUTPUT);
  pinMode(8,OUTPUT);
  pinMode(9,OUTPUT);
  pinMode(10,OUTPUT);
  pinMode(prPin,INPUT);
  Serial.begin(9600);
}

void loop()
{
    int prVal = analogRead(prPin);
    Serial.write(prVal);
    if(prVal>450)
    {
      if( (millis()/1000)%2 == 0 ) // check if even or odd number of seconds have passes since the program started
      {
        digitalWrite(5,HIGH);
        digitalWrite(6,HIGH);
        digitalWrite(7,HIGH);
        digitalWrite(8,LOW);
        digitalWrite(9,HIGH);
        digitalWrite(10,HIGH);
      }
      else
      {
        digitalWrite(5,LOW);
        digitalWrite(6,HIGH);
        digitalWrite(7,HIGH);
        digitalWrite(8,HIGH);
        digitalWrite(9,HIGH);
        digitalWrite(10,HIGH);
      }
    }
    else
    {
      digitalWrite(5,HIGH);
      digitalWrite(6,HIGH);
      digitalWrite(7,LOW);
      digitalWrite(8,HIGH);
      digitalWrite(9,HIGH);
      digitalWrite(10,LOW);
      delay(10);
    }
}


ESP2866 and java ServerSocket So I have an application that runs on the Arduino that passes info over serial.
I'm using a ESP2866 to make it wireless.

Arduino->Serial->Esp2866->SocketConn->JavaSocket->Console

I have a working java socket server, that I can connect to with other applications. (Java, c++, ext.) And even across the network.

I just cant seem to get my ESP2866 to connect.

Iv tried several ESP2866 units, no success. Iv tried updating the firmware on each, nope.

AT                      ->  OK
AT+RST                  ->  ready
AT+CWMODE=1             ->  OK
AT+CWJAP="name","pass"  ->  CONNECTED,GOTIP,OK
AT+CIPMUX=0             ->  OK
AT+CIFSR                ->  192.168.0.30
AT+CIPSTART="TCP","192.168.0.9","4160"  ->  ERROR

The lack of debug info is... Aggravating.
Iv Seen other examples of this that worked. So whats the problem?

Additional info:

netstat -tulpn | grep 4160
tcp6       0      0 :::4160          :::*      LISTEN      23058/java

(Edit 1:)Just tried restricting to IPV4 and rebinding the port. Nope.

InetAddress localAddress = Inet4Address.getByAddress(new byte[]{(byte) 192,(byte) 168,0,9});
System.setProperty("java.net.preferIPv4Stack", "true");
ServerSocket listener = new ServerSocket(port,20,localAddress);
//...Code to make socket work.

The ESP trys to connect to port 4160, but the server is listing on port 20.


Using Bluetooth module HC-05 when Arduino is powered using a battery I have a project that involves sending messages from an Android device to an Arduino using a bluetooth module. I am using an HC-05 bluetooth module and an Arduino Mega 2560.

It works as long as I power the Arduino to my laptop using a USB cable. However, I need to use an external power source and have been using a 6F22 9V battery connected through the VIN pin for this purpose, without facing any problems. But on connecting the HC-05, it does not even light up.

The Arduino is also connected to four dc motors, five servo motors (all of which are externally powered, only get digital signals from the Arduino), and seven HC-SR04 ultrasound sensors, whcih are powered through the 5V pin.

I have connected the HC-05 to the Arduino as follows:

HC-05   Arduino

VCC      3.3V

GND      GND

TX       RX

RX       TX           through a voltage divider

I am new to all this, and would be grateful for any help. Thank you.

6F22 (PP3) batteries are among the wimpiest of batteries available.  They are not a good choice for anything except extreme low power applications, and anything involving radio transmitters is definitely not an extreme low power application.

Use a better battery.  I would recommend 6 AA batteries (you can get 6xAA battery holders with the same connector as a PP3 battery) which will give you considerably more power than a little PP3.

Either that or a 7.2V "2S" Li-Ion battery pack.


How to power an Arduino Uno with 3 1.5V batteries? I have an Arduino Uno (a SainSmart model, actually). I intend to power it with three 1.5V batteries. I measured them and they yield 4.67V in total. The Arduino requires 5V.
The question is, if the arduino will work this way.
I'm not powering complicated microcontroller components here. These components are used:

A buzzer
An LED
A unit of 4 seven segment displays
A couple of buttons as input elements

If the volume or brightness of these components is slightly decreased, it doesn't matter at all. But I would like to know if it will work in the first place.
And also...
Where exactly do I plug the power source in? The power jack, the USB jack, pins, somewhere else?

The schematic looks like this, just to illustrate it. I'm not a good drawer, but you'll get the idea...

The Arduino doesn't require 5V.

The Atmel chip on the board requires somewhere between 1.8V and 5.5V, the Arduino just happens to have chosen 5V as a good common widely used voltage to run at.

If you provide a voltage within that range to the +5V pin the board will operate.  There's a couple of caveats though:

Anything below about 4V will mean the 3.3V regulator won't be working right, so the 3.3V pin won't be functioning properly
At lower voltages the Atmel chip can't operate reliably at higher frequencies, which is why 3.3V Arduino boards operate at 8MHz instead of 16Mhz.

So 3 x AA batteries is a perfect power source for running the Arduino, direct into the 5V pin.  Just make sure that you don't power it any other way at the same time or you'll be pumping 5V into your batteries.  You may want to add a Schottky diode in series with your battery + (between battery + and the 5V pin) to stop that ever causing a problem.  Choose one with a very low forward voltage drop though, otherwise you could end up dropping too much of your precious voltage over the diode.

By the way, when you're powering it from USB the 5V could be anywhere between 4.75V and 5.25V.


Does serial speed affect performance of other tasks? I have explored Google and the Arduino site and this site and cannot find a mention of this, so my guess is that serial is handled by a separate component to the core processing and so different serial communication rates will not affect code performance.

Is this correct?

Where can I find information about how serial passing is handled? For instance, when I call Serial.prinlnt("test"), how does that get to the serial line?

It depends. Serial data is received into, or sent from, buffers (one for sending and one for receiving). If you have a processor with 1024 bytes of RAM or more, then the buffer size is 64 bytes, otherwise it is 16 bytes. (See the HardwareSerial.h file in your distribution).

If the buffer fills up when sending, it will block (that is, the code will wait for the buffer to empty). If it fill up when receiving the extra bytes will be discarded.

If the buffer does not fill up, then the baud rate will not affect performance. That is because data is sent, or received, by an interrupt service routine, in the background.

As a rule of thumb, you can expect data to be sent or received at the baud rate divided by 10. That is because each byte is 8 bits, plus a start and a stop bit (10 bits in total).

So, for example, at 9600 baud you can send 960 characters per second. If you are sending something simple, like a temperature which is 20 bytes, every second, then the baud rate won't affect performance at all. If you are trying to send thousands of bytes per second, it will affect performance, because the Serial.println will probably block once the buffer fills up.

  For instance, when I call Serial.prinlnt("test"), how does that get to the serial line?

If the buffer is not full, then "t" "e" "s" "t" are copied into the buffer, and the code returns immediately. If the buffer is full then it waits for it to become not-full.

As an efficiency measure, if you are sending a single byte, and the buffer is empty, then the byte is placed in the hardware register immediately (saving a small amount of time). In this case, if the buffer was empty, "t" would be sent immediately, and "est" would be sent afterwards, as a "byte has been sent" interrupt is raised.1

This is described in the code comments:

size_t HardwareSerial::write(uint8_t c)
{
  _written = true;
  // If the buffer and the data register is empty, just write the byte
  // to the data register and be done. This shortcut helps
  // significantly improve the effective datarate at high (>
  // 500kbit/s) bitrates, where interrupt overhead becomes a slowdown.
  if (_tx_buffer_head == _tx_buffer_tail && bit_is_set(*_ucsra, UDRE0)) {
    *_udr = c;
    sbi(*_ucsra, TXC0);
    return 1;
  }
  tx_buffer_index_t i = (_tx_buffer_head + 1) % SERIAL_TX_BUFFER_SIZE;

  // If the output buffer is full, there's nothing for it other than to
  // wait for the interrupt handler to empty it a bit
  while (i == _tx_buffer_tail) {
    if (bit_is_clear(SREG, SREG_I)) {
      // Interrupts are disabled, so we'll have to poll the data
      // register empty flag ourselves. If it is set, pretend an
      // interrupt has happened and call the handler to free up
      // space for us.
      if(bit_is_set(*_ucsra, UDRE0))
    _tx_udr_empty_irq();
    } else {
      // nop, the interrupt handler will free up space for us
    }
  }

  _tx_buffer[_tx_buffer_head] = c;
  _tx_buffer_head = i;

  sbi(*_ucsrb, UDRIE0);

  return 1;
}

Notice that the byte is not placed in the buffer at all if it is empty, and nothing is being sent.

For more information see my question and answer about serial processing.

Strictly speaking, after discussing this in the comments with Majenko, the interrupt that is raised is really that the hardware "send" buffer is empty. When the send buffer empties then the interrupt is called so that the interrupt code can put a new byte into it.


Is it possible to use the Arduino Due's specials pins for digital writing and reading? Hello the arduino documentation on the due specifies the pin mapping of the pins.I am making a custom board using the dues schematics and i am running still a bit low on pins. Also some of the special pins offer a better position for traces.

So is it possible digitalWrite()/digitalRead() the specials pins such as:

RX (0-3)
TX (0-3)
SDA (0-1)
SCL (0-1)
CANRX
CANTX
LED RX
LED TX
MISO
MOSI
SCLK

As for the SPI and i2c lines i will be using them for the original purpose,but i would like to take the opportunity to know anyway.

I do not own a due so unfortunately i can not test it

Yes, although you may need to modify the variant files to allow access to them.

Every function on the SAM3X8E is a "multiplexed" function. That is, it shares pins with other functions.  For example CANTX0 is an alternative function on pin PA0.

You can find all the alternative function mappings on page 40 of the datasheet.

You may find that many of these pins already have an Arduino pin number assigned to them in the variant file. If that is the case then you can just use it as you would any digital IO pin.

I have included the comments from the variant files here for quick reference:

/*
 * DUE Board pin   |  PORT  | Label
 * ----------------+--------+-------
 *   0             |  PA8   | "RX0"
 *   1             |  PA9   | "TX0"
 *   2       TIOA0 |  PB25  |
 *   3       TIOA7 |  PC28  |
 *   4       NPCS1 |  PA29  |
 *           TIOB6 |  PC26  |
 *   5       TIOA6 |  PC25  |
 *   6       PWML7 |  PC24  |
 *   7       PWML6 |  PC23  |
 *   8       PWML5 |  PC22  |
 *   9       PWML4 |  PC21  |
 *  10       NPCS0 |  PA28  |
 *           TIOB7 |  PC29  |
 *  11       TIOA8 |  PD7   |
 *  12       TIOB8 |  PD8   |
 *  13       TIOB0 |  PB27  | LED AMBER "L"
 *  14       TXD3  |  PD4   | "TX3"
 *  15       RXD3  |  PD5   | "RX3"
 *  16       TXD1  |  PA13  | "TX2"
 *  17       RXD1  |  PA12  | "RX2"
 *  18       TXD0  |  PA11  | "TX1"
 *  19       RXD0  |  PA10  | "RX1"
 *  20             |  PB12  | "SDA"
 *  21             |  PB13  | "SCL"
 *  22             |  PB26  |
 *  23             |  PA14  |
 *  24             |  PA15  |
 *  25             |  PD0   |
 *  26             |  PD1   |
 *  27             |  PD2   |
 *  28             |  PD3   |
 *  29             |  PD6   |
 *  30             |  PD9   |
 *  31             |  PA7   |
 *  32             |  PD10  |
 *  33             |  PC1   |
 *  34             |  PC2   |
 *  35             |  PC3   |
 *  36             |  PC4   |
 *  37             |  PC5   |
 *  38             |  PC6   |
 *  39             |  PC7   |
 *  40             |  PC8   |
 *  41             |  PC9   |
 *  42             |  PA19  |
 *  43             |  PA20  |
 *  44             |  PC19  |
 *  45             |  PC18  |
 *  46             |  PC17  |
 *  47             |  PC16  |
 *  48             |  PC15  |
 *  49             |  PC14  |
 *  50             |  PC13  |
 *  51             |  PC12  |
 *  52       NPCS2 |  PB21  |
 *  53             |  PB14  |
 *  54             |  PA16  | "A0"
 *  55             |  PA24  | "A1"
 *  56             |  PA23  | "A2"
 *  57             |  PA22  | "A3"
 *  58       TIOB2 |  PA6   | "A4"
 *  69             |  PA4   | "A5"
 *  60       TIOB1 |  PA3   | "A6"
 *  61       TIOA1 |  PA2   | "A7"
 *  62             |  PB17  | "A8"
 *  63             |  PB18  | "A9"
 *  64             |  PB19  | "A10"
 *  65             |  PB20  | "A11"
 *  66             |  PB15  | "DAC0"
 *  67             |  PB16  | "DAC1"
 *  68             |  PA1   | "CANRX"
 *  69             |  PA0   | "CANTX"
 *  70             |  PA17  | "SDA1"
 *  71             |  PA18  | "SCL1"
 *  72             |  PC30  | LED AMBER "RX"
 *  73             |  PA21  | LED AMBER "TX"
 *  74       MISO  |  PA25  |
 *  75       MOSI  |  PA26  |
 *  76       SCLK  |  PA27  |
 *  77       NPCS0 |  PA28  |
 *  78       NPCS3 |  PB23  | unconnected!


Using ATiny102 as HID device(emulating mouse) I am trying to make my own mouse/keyboard from an attiny (it doesn't have to be attiny102 as the title suggests). I have read many articles on this subject: some are using v-usb library.But I understand this is for arduino uno/leonardo.I want to use an attiny with the least amount of electronic parts attached to it(no external oscillator-only the internal one..etc.). All the articles I read said that arduino can't be used as a host usb device but this applies only for it's built-in micro-usb. Can't I just emulate the HID device using digital pins on my attiny? If this is possible where can you provide some well-documented source for the protocol used when communicating with the pc?

I have build a HID midi keyboard with the hiduino lib which is base on LUFA.
http://code.google.com/p/hiduino/w/list

I know LUFA is also capable to build a HID mouse device. But you need to switch to a bigger controller (i think). I used a 8u2 from atmel.

I used AVR Studio 6 to compile hiduino.
Currently i have no link to the LUFA because the git page is gone. Maybe you find a mirror or a other webpage.


What's the newest way to use C++ stdlibs in Arduino 1.8.2? (My Arduino version is 1.8.2.)

For example,if I want to #include <vector> or <string>, <iostream>, <memory> etc, the compiler always complains that such libs are not found.

So what's the newest/most efficient way to use C++ libs in Arduino 1.8.2?

Most Arduino Core don't include the Standard C++ Library, that's why headers like <vector> and <string> are missing.
This decision makes a lot of sense because the STL relies heavily on heap allocation, which would ruin the little RAM of the microcontroller.

If you're looking for an alternative to the STL, you might check out the ETL, the Embedded Template Library.. However, the code will not be the same because all the containers of the ETL have a fixed capacity. Here is a string for example:

etl::string<32> s = "hello world";

In practice, I never saw a project using the ETL. Most projects use the standard Arduino classes (String, Stream, Print...) and learn to live with their flaws. Since there are no generic container classes in the Arduino core, the common usage is to use plain old C arrays.


Interrupt fires multiple times I have a Photo Interrupter which I am using to count the RPM of a motor.

I am incrementing an integer to show the amount of interrupts there have been.

The issue is that there can be several interrupts fired for each time the "beam" of the Photo Interrupter is broken.

I have a 5mm length of plastic which breaks the "beam". If I make the plastic shorter than that, the Photo Interrupter doesn't pick up the break.

I am using the following, very basic code:

int pin = 13;
volatile  int tcnt = 0;
volatile int state = LOW;

void setup() {
  Serial.begin(9600);
  pinMode(pin, OUTPUT);
  attachInterrupt(0, blink, CHANGE);
}

void loop() {
  Serial.println(tcnt);
  digitalWrite(pin, state);
}

void blink() {
  tcnt = tcnt + 1;
  state = !state;
}

Two other possible problems, apart from what Jake C has adressed in his answer are:

1. Hardware bounce

If your signal from the sensor isn't a clean transition from high to low but rather "bouncy" (see image below). The microcontroller will register multiple transitions in the meantime.

Solution to this would be to add a small capacitor (wil slow it down though) or add debouncing code... Best would be to get a "clean" sensor.

2. Floating contact

  When I even move my finger close to the wire running to PIN2 the interrupt fires.

That kinda seems like it's a floating contact, where it's not really connected to anything.

This is usually solved by using a pullup/pulldown resistor. Or maybe there is something wrong with the connection.

Also:

  Maybe due to the type of sensor?

You should note the part number of the sensor or link a datasheet, so we can see if it's typical behaviour for this type of sensor.


How to Connect TFT LCD display with NodeMCU? I am doing this project wherein I want to display some image on the LCD screen. I am having a problem with the connecting nodemcu with my TFT LCD screen. I cannot find any references. Does a TFT screen go well with a NodeMCU? if yes, please help

I tried taking refrence from this website but i ended up damaging my nodeMCU

http://nobrok.com/connecting-tft-lcd-touch-screen-with-nodemcu-esp8266/

Also attaching images of TFT display and my NodeMCU.

It would be great if you can help. Thanks :)

According to its web site, the TFT module does have SPI interface. https://www.jixin.pro/product/717.html
The site is in Chinese though.


How to stop Arduino from reseting after serial connection lost If I connect to an Arduino Uno via a serial console to read debugging statements and then disconnect, the Arduino appears to reset. How do I stop this from happening?

I'm trying to program an Arduino to receive a "shutdown" signal from a Raspberry Pi via serial, which will make the Arduino cut the RPi's power. However, this will also cut the serial connection, and if it causes the Arduino to reset, it'll reactivate power.

There is a link on the Uno marked RESET-EN which links the Atmega16U2 (or 8U2) which handles incoming serial data to the main chip, the Atmega328P. If you cut that link (eg. with a knife) then it won't reset. However uploading new sketches will be harder because you will have to manually press the Reset button when the IDE starts to upload a new sketch.

Board:

Schematic:

One thing that people do is put a 10 µF capacitor between RESET and GND. That holds enough current to "weather" the reset pulse, and that stops the board resetting. You can always remove the capacitor to reprogram the board.


Press on pressure sensor once, turn on LED for 6 seconds I am working on a project where I would like to press on a pressure sensor (0-1024) once and turn on the LED and turn off by itself after 6 seconds. I am quite new to arduino and I can't seem to understand how to code this with using a pressure sensor as a switch rather than an actual switch. Any ideas?

Sensors which give a range of outputs need to have their outputs processed using a technique called hysteresis.  That is, normally, the turn on threshold is higher then the turn off threshold.

For example, the thermostat in your home uses hysteresis when controlling your HVAC system.  Otherwise your thermostat would constantly be turning on and off your HVAC system likely causing an early failure.

Here is a stackexchange Arduino question about hysteresis.


PCA9685: how "unset" PWM signal? I use my Arduino with Adafruit PCA9685 servo controller. To set PWM signals I use the provided library: https://github.com/adafruit/Adafruit-PWM-Servo-Driver-Library

It allows easily set PMM signal and works good. But how can I "unset" PWM signal for a certain pin?

If a PWM siganl is active, the servo stucks on the current position and can't be moved by hand, but only by setting other pulse length. So I need to move servo and then "free" it.

You could try changing the corresponding pin from output to input.
To be sure not to disturb other comfigurations you could do direct port manipulation.

void servo_off() {
  DDRD &= ~(1<<PD5);
}

void servo_on() {
  DDRD |= (1<<PD5);
}

This assumes you use pin PD5 for the pwm signal. Adjust the "D" in DDRD and PD5 so it matches the port in use as well as the pin number.

Of course, you need some additional user input like a button to trigger calls to those functions.


Running a 7 pin OLED with 4 pins (I2C) I have an OLED with this 7 pin pinout:

I want to use an existing code i found that makes use of U8Glib.
But in the example, use uses 4 pins to control the OLED via I2C.
This is the pinout he uses:

Is it possible to control my OLED via 4 pins and use U8Glib to simplify my project by making use of the example code i found?

EDIT: Here is also a picture of the back of the OLED PCB that mentions how to use IIC but i do not understand it!

This page has the answer to your questions. For reference:

  Setting up SPI/I2C Connection with GMS096A OLED Module

  Being a new entry to the market, only limited resources are available
  on this small piece of miracle (GMS096A). I2C/SPI configuration always
  demands helpful resources as in any case. For the SPI setup, the
  module comes in 4 wire SPI configuration by default and to make it
  work with the arduinos you can use these libraries from Adafruit.

  For the I2C setup it demands a little bit of work on the module.
  Actually it was one of our customers who shared these simple
  configuration steps with us, start with resoldering the resistor from
  position R3 to R1 and then short the R8 resistor with some solder tin
  (0 Ohm resistor). The R6 and R7 pullup resistors are already soldered,
  nothing to do there. Once done, the module is ready for I2C
  communication! The CS Pin is not necessarily needed, so just connect
  it to GND. The DC Pin selects the address. For standard address wire
  it to GND. The RES-pin needs a low pulse at startup and high voltage
  during operation (as in SPI mode), a 100nF capacitor to GND and a 10k
  res to VCC would be ideal!

Your module might differ sightly. But you should be able to figure it out from there. The pulse on the RES-pin needed at startup took me a while to figure out!


How is the bootloader activated when device is running? For the sake of specificity I am referencing my question to Arduino. It applies to all AVRs with hardware USB and a bootloader though.

The bootloader is capable of receiving new program data over the USB interface, and, after programming, releases the interface. It can then for instance be used for the emulation of a serial port, or even register as a HID.

I know what a bootloader is and how it reads program data from the PC and how it writes it to the devices flash memory.

I am asking how the bootloader is triggered again if the user wants to upload a new program. The PC needs to reset the AVR in order to fire up the bootloader. How is this reset instruction implemented in Arduinos with built-in USB hardware (e.g. the Arduino Micro)? Is it solved by performing a software reset after the DTR line goes low just as in e.g. the Arduino Nano, except that the DTR line only exists in software?

EDIT: If that is the case, the solution is unique to Arduinos. I was thinking that there would be some standard way of doing it common to all AVRs.

On microcontrollers with bootloader (not just AVRs), the bootloader is a separate executable in flash, and it's typically the program that runs on system startup.  The application will have a special trigger, such as a button sequence, getting a specific byte sequence over I2C, or really anything that will tell the bootloader to enter into its "update" mode.  From there, the bootloader will have some communication (I2C, USB, WiFi, serial, etc) to download and the flash the new application image.

This link has more information about the Arduino bootloader

  On the PC side, to trigger a reset on the RESET pin, the PC (avrdude.exe or GNU/Linux equivalent) opens the serial port to Arduino when your press upload and the code is ready to upload. This causes the Data Transmit Ready (DTR) line of the USB/TTL chip to go LOW. The Arduino board has a capacitor charging circuit that uses this LOW (charging the capacitor) signal to momentarily pull down the RESET line of the ATMEGA328P chip before returning it to HIGH (capacitor charging completes). So Arduino resets each time its serial port is opened.

  Upon reset, Arduino enters the bootloader.

  The bootloader looks at the source that caused the reset. There are several sources that can cause a reset. If the reset was caused by the RESET pin, then it waits for one second for the PC to send in commands. When it receives valid commands, it will start accepting new Arduino code in HEX format and erase the existing code to load new one. If it doesn’t receive valid commands, it times out after one second and triggers a Watch Dog Timer (WDT) reset.

For Arduinos with built-in USB, such as the Micro, the Arduino library (firmware) triggers the system reset.  There's a little chunk of code that looks for the virtual COM port to open at 1200 baud and then close.  When that happens, the code triggers a system reset (by writing a register, typically) which launches the bootloader.

  Rather than requiring a physical press of the reset button before an upload, the Micro board is designed in a way that allows it to be reset by software running on a connected computer. The reset is triggered when the Micro's virtual (CDC) serial / COM port is opened at 1200 baud and then closed. When this happens, the processor will reset, breaking the USB connection to the computer (meaning that the virtual serial / COM port will disappear). After the processor resets, the bootloader starts, remaining active for about 8 seconds. The bootloader can also be initiated by pressing the reset button on the Micro. Note that when the board first powers up, it will jump straight to the user sketch, if present, rather than initiating the bootloader.

  Because of the way the Micro handles reset it's best to let the Arduino Software (IDE) try to initiate the reset before uploading, especially if you are in the habit of pressing the reset button before uploading on other boards. If the software can't reset the board, you can always start the bootloader by pressing the reset button on the board.

Personal story: I wrote an I2C bootloader for the PIC32.  The only communication with the device was through the I2C bus.  The main application had a special 3 byte trigger that would set a non-initialized variable in RAM, and then trigger a system reset.  The bootloader, which runs on system startup, would check that variable and if it was set, would wait for commands over I2C to download and flash the new application image.  That variable in RAM had to be specially marked as non-initialized, otherwise the C startup code would clear it and the bootloader would never update.

The bootloader also calculated a CRC32 over the application image to validate it before attempting to boot.  If the calculated CRC32 didn't match the stored CRC32 (which was part of the application image), then the bootloader would enter its firmware update mode.  This was a guard against trying to run a corrupted firmware image, which could happen if power was pulled during the update process.


PC not recognizing Arduino when working with a class and MIDIUSB library I've recently bought an Arduo Due to create some sort of a Midi controller together with the MIDIUSB library.

I have create a simple a test program with 1 potentiometer (without the use of a class) to test the MIDIUSB library and everything works fine, so I decided to expanded my program to make it work with more than 1 potentiometer (with the use of a class).

However my pc stopped recognizing my Arduino as a MIDI device with my updated code. When I upload my previous example code it all works fine. I get no compile errors or whatsoever.
I don't understand what I'm doing wrong.
If anybody could explain me what I'm doing wrong or could give me a solution you would be a hero since I can't really work further if this issue doesn't get resolved.
Thanks!

Here is my code for Custom_MIDI_controller_V2.ino:

#include "MIDIUSB.h"
#include "Class.h"
#define TOLERANCE 8

byte NUMBER_POTS = 5;

Pot PO0(A0, 1, 14);
Pot PO1(A1, 1, 15);
Pot PO2(A2, 1, 16);
Pot PO3(A3, 1, 17);
Pot PO4(A4, 1, 18);

Pot *POTS[] = {&PO0, &PO1, &PO2, &PO3, &PO4};

void setup() {

}

void loop() {
  for (int i = 0; i < NUMBER_POTS; i++) {
    int potValue = POTS[i]->getValue();
      if(potValue != 255) {
        controlChange(POTS[i]->_channel, POTS[i]->_control, potValue);
        MidiUSB.flush();
      }
   }
}

void controlChange(byte channel, byte control, byte value) {
  midiEventPacket_t event = {0x0B, 0xB0 | channel, control, value};
  MidiUSB.sendMIDI(event);
}

Here is my Class.cpp code:

#include "Arduino.h"
#include "Class.h"

#define TOLERANCE 8

Pot::Pot(int pin, int channel, int control) {
  _pin = pin;
  _channel = channel;
  _control = control;
  _value = analogRead(_pin);
  _oldValue = _value - 10;
}

int Pot::getValue() {
  int diff = abs(_value - _oldValue);
  if(diff > TOLERANCE)
  {
    _oldValue = _value;
    return map(_value, 0, 1023, 127, 0);
  } else {
    return 255;
  }
}

And this is my header Class.h code:

#ifndef Class_h
#define Class_h
#include "Arduino.h"

class Pot
{
  public:
    Pot(int pin, int channel, int control);
    int getValue();
    int _pin;
    int _channel;
    int _control;
    int _value;
    int _oldValue;
};

#endif

You need to take care with constructors in C++.  They get called during the global variable initialisation phase of the execution, which happens before main() gets called.

main() calls the routines that initialise and configure the peripherals and such in the chip, and by having analogRead() in your constructor (which is itself another error I will mention below) there is a good chance (I don't know the full initialisation sequence of that chip though) that it will never complete, and thus your program hangs at that point.

Your analogRead() doesn't want to be in the constructor, anyway, since that will only execute once when the object is constructed.  Instead you want to have analogRead() called at the point you need to get the analog value. In your code that would be at the start of int Pot::getValue().


Why do you need a second resistor when using a photoresistor/LDR? A photoresistor is already a resistor and will limit the voltage in the circuit. Why can't this be connected to a pin and measured? Why is a second resistor needed to connect the photoresistor to ground?

The simple answer is that voltage is very easy for the Arduino to measure, while resistance is not, and most sensors such as Photoresistor (LDR), flex sensor, thermistors and more - are actually a variable resistors.

The main reason it's hard to measure resistance changes is that the Arduino (and most IC) contain a tiny system called Analog to Digital Converter (ADC). This system translates changes in analog voltage to a series of 1's and 0's that can be in turn converted to an Integer for example.

The ADC is designed to read voltage changes, and if we want to use the Arduino's analogRead (which utilizes the ADC) to get the Photoresistor readings for example, we will need a way to convert the changes in resistance to changes in voltage - and a voltage divider is the easiest way to do it.

It is true that the sensor is already a resistor, and as such it should change the voltage across it. But you would have trouble measuring the voltage changes, since there is no reference point except for Vcc (5V) and Ground:

In contrary, when using a voltage divider, you have a well defined reference point to measure the voltage changes:


Having trouble figuring out CTC on Timer 1 with ATTiny85 I'm using Timer1 on the Attiny85 clocked at 1MHz to toggle an LED every 1 second. However, I'm having some issues regarding prescaler and OSC value selection.

I'm using this formula, which I found in the datasheet for the Attiny.

fOCnx = fclk/(2*N*(1+OCRnx))

N = Prescaler
I'm taking fOCnx = 0.5Hz as I want a square wave
So based on the above formula, I tried the following cases

N = 2048, OCR1C = 243
N = 4096, OCR1C = 122
N = 8192, OCR1C = 61
N = 16384, OCR1C = 30

The LED toggles after an interval of 1s for cases 3 and 4. However, for cases 1 and, it seems to toggle after 2 seconds. Can anyone tell me why this is happening? Eventually, I want to use this to time data acquisition from a sensor I have so I need to be accurate.

Here's my code

#include <SoftwareSerial.h>

int ledPin = 1;
int state = 0;

SoftwareSerial ser(3, 4);
void setup() {
  // put your setup code here, to run once:
  TCCR1 |= 0x8F;
  OCR1C = 30;
  TIMSK = (1 << OCIE1A);
  pinMode(ledPin, OUTPUT);
  ser.begin(9600);
}

ISR(TIMER1_COMPA_vect)
{
  state = !state;
  digitalWrite(ledPin, state);
  ser.println(state);
}

void loop() {
  // put your main code here, to run repeatedly:
}

The only explanation I have is, that the Software serial switch off the interrupts globally when it operates (print). If interrupts are locked when the timer completes, you loose a tick. It does not explain the different behavior of the four value pairs, but there are some issues reported in a german forum. They did not find an answer, but the assumed it depends on the 'delay()' function, that is used for the software serial and the fact that the interrupts are locked to make the delay function more exact.

If you want to be sure, you can try this by completely removing the Software Serial from your program. If you make the values switchable by e.g. a button press you can change it without having to reload the program. Then it's easier to see different  blinking intervals.

int ledPin = 1;
int state = 0;

int regValues[] = { 0x8f, 0x8e, 0x8d, 0x8c };
int cntValues[] = { 30, 61, 122, 243 };

const int buttonPin = 2;
int buttonState = LOW;

long lastDebounceTime = 0;
long debounceDelay = 80;
int lastButtonState = LOW;

int pairIndex = 0;

void setup()
{
  TCCR1 = regValues[ pairIndex ];
  OCR1C = cntValues[ pairIndex ];

  TIMSK = (1 << OCIE1A);

  pinMode(ledPin, OUTPUT);
  pinMode(buttonPin, INPUT);
}

ISR(TIMER1_COMPA_vect)
{
  state = !state;
  digitalWrite(ledPin, state);
}

void loop()
{
  int reading = digitalRead(buttonPin);

  if (reading != lastButtonState)
  {
    lastDebounceTime = millis();
  }

  if ( (millis() - lastDebounceTime) > debounceDelay)
  {
   if (reading != buttonState)
   {
      buttonState = reading;

      if (buttonState == HIGH)
      {
        if ( ++pairIndex > 3 )
        {
          pairIndex = 0;
        }

        TCCR1 = regValues[ pairIndex ];
        OCR1C = cntValues[ pairIndex ];
      }

    }

  }

}

I wrote this code without having a attiny to testing it. So hopefully all is correct. If you would try it, can you please report any errors, so I can correct them?


NRF24L01 receiving even if no data sent I am using nRF24L01 to communicate between two micro controllers. Both are Arduino Uno.

The question i have here is , even if i do not send any data from sender to receiver , the receiver device is constantly checking for the data, and the blank data is being received per second. And also no data is received by receiver which is sent by sender.

I am sharing the code for both sender and receiver.

Please suggest me what wrong i am doing.

Receiver Code :

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>

RF24 radio(7, 8); // CNS, CE
String response;
boolean done = false;

void setup() {

 delay(500);
 Serial.begin(9600);

 radio.begin();
 radio.setPALevel(RF24_PA_MIN);
 radio.openReadingPipe(0, 0xF0F0F0F0AA);
 radio.startListening();

}

void loop() {

   if (radio.available()) {

   radio.read(&response, sizeof(response));
   done = true;

}

if (done) {
  Serial.println(response);
}

done = false;
delay(1000);

}

Sender Code:

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>

RF24 radio(7, 8); // CNS, CE
String request;

void setup() {

delay(500);
Serial.begin(9600);

radio.begin();
radio.openWritingPipe(0xF0F0F0F0AA);
radio.setPALevel(RF24_PA_MIN);
radio.stopListening();

}

void loop() {

   while ( Serial.available() > 0 )  {

   request = Serial.readString();

   Serial.println(request);
   radio.write(&request, sizeof(request));

   delay(1000);

 }
}

I've written a code for NRF24L01+ based on the datasheet.run them on your arduino and test them.CE pin is PIN7 in arduino and CSN is PIN8 in arduino.
NRF_monitorRegisters() shows all Registers of NRF.It's nice to test your NRF
maybe it helps:

for transmitter:

#include <SPI.h>

int sending = 1;
int data = 7;

void IRQ() {
  Serial.println("STATUS register from IRQ ISR :  ");
  digitalWrite(8, 0);
  SPI.transfer(0x07);
  delay(10);
  Serial.println(SPI.transfer(0xff), BIN);
  delay(10);
  digitalWrite(8, 1);

  digitalWrite(8, 0);
  SPI.transfer(0x08);
  delay(10);
  Serial.println(SPI.transfer(0xff), BIN);
  delay(10);
  digitalWrite(8, 1);

  digitalWrite(8, 0);
  SPI.transfer(0x07 + 0x20);
  delay(10);
  SPI.transfer(0xff);
  delay(10);
  digitalWrite(8, 1);
}

void NRF_transmitterBegin() {

  //reading
  /*digitalWrite(8, 0);
    SPI.transfer(0x00);
    delay(10);
    Serial.println(SPI.transfer(0xff), BIN);
    delay(10);
    digitalWrite(8, 1);*/

  pinMode(7, OUTPUT);  //CE
  pinMode(8, OUTPUT);  //CSN
  delay(100);
  digitalWrite(8, 1);
  digitalWrite(7, 0);

  SPI.setBitOrder(MSBFIRST);
  SPI.setDataMode(SPI_MODE0);
  SPI.setClockDivider(SPI_CLOCK_DIV4);
  SPI.begin();
  delay(1000);

  digitalWrite(8, 0);   //flush TX_FIFO
  SPI.transfer(0xe1);
  delay(10);
  digitalWrite(8, 1);

  digitalWrite(8, 0);   //flush RX_FIFO
  SPI.transfer(0xe2);
  delay(10);
  digitalWrite(8, 1);

  digitalWrite(8, 0);
  SPI.transfer(0x07 + 0x20);
  delay(10);
  SPI.transfer(0xf0);
  delay(10);
  digitalWrite(8, 1);

  digitalWrite(8, 0);
  SPI.transfer(0x00 + 0x20);
  delay(10);
  SPI.transfer(0x0e);
  delay(10);
  digitalWrite(8, 1);
  delay(10);

  /*digitalWrite(8, 0);
    SPI.transfer(0x11 + 0x20);
    delay(10);
    SPI.transfer(0x3f);
    delay(10);
    digitalWrite(8, 1);*/

  //Down for DYNPL
  digitalWrite(8, 0);
  SPI.transfer(0x1c + 0x20);
  delay(10);
  SPI.transfer(0x01);
  delay(10);
  digitalWrite(8, 1);

  digitalWrite(8, 0);
  SPI.transfer(0x1d + 0x20);
  delay(10);
  SPI.transfer(0x04);
  delay(10);
  digitalWrite(8, 1);
  //Up for DYNPL

  digitalWrite(8, 0);
  SPI.transfer(0x01 + 0x20);
  delay(10);
  SPI.transfer(0x3f);
  delay(10);
  digitalWrite(8, 1);

  digitalWrite(8, 0);
  SPI.transfer(0x02 + 0x20);
  delay(10);
  SPI.transfer(0x03);
  delay(10);
  digitalWrite(8, 1);

  digitalWrite(8, 0);
  SPI.transfer(0x03 + 0x20);
  delay(10);
  SPI.transfer(0x03);
  delay(10);
  digitalWrite(8, 1);

  digitalWrite(8, 0);
  SPI.transfer(0x04 + 0x20);
  delay(10);
  SPI.transfer(0xff);
  delay(10);
  digitalWrite(8, 1);

  digitalWrite(8, 0);
  SPI.transfer(0x05 + 0x20);
  delay(10);
  SPI.transfer(0x4c);
  delay(10);
  digitalWrite(8, 1);

  digitalWrite(8, 0);
  SPI.transfer(0x06 + 0x20);
  delay(10);
  SPI.transfer(0x06);
  delay(10);
  digitalWrite(8, 1);

  digitalWrite(8, 0);
  SPI.transfer(0x0a + 0x20);
  delay(10);
  SPI.transfer(0xaa);
  delay(10);
  SPI.transfer(0xaa);
  delay(10);
  SPI.transfer(0xaa);
  delay(10);
  SPI.transfer(0xaa);
  delay(10);
  SPI.transfer(0xaa);
  delay(10);
  digitalWrite(8, 1);

  digitalWrite(8, 0);
  SPI.transfer(0x10 + 0x20);
  delay(10);
  SPI.transfer(0xaa);
  delay(10);
  SPI.transfer(0xaa);
  delay(10);
  SPI.transfer(0xaa);
  delay(10);
  SPI.transfer(0xaa);
  delay(10);
  SPI.transfer(0xaa);
  delay(10);
  digitalWrite(8, 1);

  attachInterrupt(digitalPinToInterrupt(2), IRQ, FALLING);
  delay(10);

}

void NRF_transmit(int whatIsData , float data , float hum) {    //hum is used just for temp&humidity
  /*
     byte 0 says what is our data:  1 -> data and humidity    2 -> movement   3 -> gas

     1(float) :   byte 1 -> integer part of temp  byte 2 -> fractional part of temp   byte 3 -> integer part of humidity    byte 4 -> fractional part of humidity    byte 5 -> %battery
     2(binary) :  byte 1 -> %battery
     3(float) :   byte 1 -> integer part of gas   byte 2 -> fractional part of gas    byte 3 -> %battery

     %battery feature is in progress ...
  */

  int byte0 = 0 , byte1 = 0 , byte2 = 0 , byte3 = 0 , byte4 = 0 , byte5 = 0;
  float buf = 0;

  byte0 = whatIsData;

  switch (whatIsData) {
    case 1: {

        byte1 = data;
        buf = data - byte1;
        byte2 = buf * 10;

        byte3 = hum;
        buf = hum - byte3;
        byte4 = buf * 10;

        break;
      }
    case 2: {

        break;
      }
    case 3: {

        byte1 = data;
        buf = data - byte1;
        byte2 = buf * 10;

        break;
      }
    default: {
        break;
      }
  }

  digitalWrite(8, 0);
  SPI.transfer(0xe1);   //flush TX_FIFO empty
  delay(10);
  digitalWrite(8, 1);

  digitalWrite(8, 0);
  SPI.transfer(0xa0);   //write on TX_FIFO
  delay(10);
  SPI.transfer(byte0);
  delay(10);
  SPI.transfer(byte1);
  delay(10);
  SPI.transfer(byte2);
  delay(10);
  SPI.transfer(byte3);
  delay(10);
  SPI.transfer(byte4);
  delay(10);
  SPI.transfer(byte5);
  delay(10);
  digitalWrite(8, 1);

  digitalWrite(7, 1);   //CE High
  delay(1);
  digitalWrite(7, 0);   //CE Low

}

void NRF_monitorRegisters() {

  for (int i = 0; i < 30; i++) {
    digitalWrite(8, 0);
    SPI.transfer(i);
    delay(10);
    Serial.print(i , HEX);
    Serial.print(" -> ");
    Serial.println(SPI.transfer(0xff), BIN);
    delay(10);
    digitalWrite(8, 1);
  }
  Serial.println("");

}

void setup() {

  Serial.begin(115200);

  NRF_transmitterBegin();
  NRF_monitorRegisters();

}

void loop() {

  NRF_transmit(3 , 15.1 , 0);

  delay(1000);
}

for receiver :

#include <SPI.h>

long int lastTime = 0;

void IRQ() {

  int whatIsData = 0;
  int byte1 = 0 , byte2 = 0 , byte3 = 0 , byte4 = 0 , byte5 = 0;
  float data = 0 , hum = 0 , buf = 0;

  /*Serial.println("STATUS register from IRQ ISR :  ");
    digitalWrite(8, 0);
    SPI.transfer(0x07);
    delay(10);
    Serial.println(SPI.transfer(0xff), BIN);
    delay(10);
    digitalWrite(8, 1);*/

  digitalWrite(8, 0);
  SPI.transfer(0x61);
  delay(10);
  whatIsData = SPI.transfer(0xff);
  delay(10);
  byte1 = SPI.transfer(0xff);
  delay(10);
  byte2 = SPI.transfer(0xff);
  delay(10);
  byte3 = SPI.transfer(0xff);
  delay(10);
  byte4 = SPI.transfer(0xff);
  delay(10);
  byte5 = SPI.transfer(0xff);
  delay(10);
  digitalWrite(8, 1);

  digitalWrite(8, 0);   //flush RX_FIFO
  SPI.transfer(0xe2);
  delay(10);
  digitalWrite(8, 1);

  digitalWrite(8, 0);
  SPI.transfer(0x07 + 0x20);
  delay(10);
  SPI.transfer(0xf0);
  delay(10);
  digitalWrite(8, 1);
  delay(10);

  switch (whatIsData) {
    case 1: {

        buf = byte2;
        data = byte1 + buf / 10;
        buf = byte4;
        hum = byte3 + buf / 10;

        Serial.print("Received data from DHT22 -> temp:");
        Serial.print(data);
        Serial.print("  humidity:");
        Serial.println(hum);

        break;
      }
    case 2: {

        Serial.println("Received data from PIR -> Move detected");

        break;
      }
    case 3: {

        buf = byte2;
        data = byte1 + buf / 10;

        Serial.print("Received data from gas sensor -> %gas:");
        Serial.println(data);

        break;
      }
    default: {

        Serial.println("a problem accured");

        break;
      }
  }

}

void NRF_receiverBegin() {

  //reading
  /*digitalWrite(8, 0);
    SPI.transfer(0x00);
    delay(10);
    Serial.println(SPI.transfer(0xff), BIN);
    delay(10);
    digitalWrite(8, 1);*/

  pinMode(7, OUTPUT);  //CE
  pinMode(8, OUTPUT);  //CSN
  delay(100);
  digitalWrite(8, 1);
  digitalWrite(7, 0);

  SPI.setBitOrder(MSBFIRST);
  SPI.setDataMode(SPI_MODE0);
  SPI.setClockDivider(SPI_CLOCK_DIV4);
  SPI.begin();
  delay(100);

  digitalWrite(8, 0);   //flush TX_FIFO
  SPI.transfer(0xe1);
  delay(10);
  digitalWrite(8, 1);

  digitalWrite(8, 0);   //flush RX_FIFO
  SPI.transfer(0xe2);
  delay(10);
  digitalWrite(8, 1);

  digitalWrite(8, 0);
  SPI.transfer(0x07 + 0x20);
  delay(10);
  SPI.transfer(0xf0);
  delay(10);
  digitalWrite(8, 1);
  delay(10);

  digitalWrite(8, 0);
  SPI.transfer(0x00 + 0x20);
  delay(10);
  SPI.transfer(0x0f);
  delay(10);
  digitalWrite(8, 1);
  delay(10);

  /*digitalWrite(8, 0);
    SPI.transfer(0x11 + 0x20);
    delay(10);
    SPI.transfer(0x01);
    delay(10);
    digitalWrite(8, 1);*/

  //Down for DYNPL
  digitalWrite(8, 0);
  SPI.transfer(0x1c + 0x20);
  delay(10);
  SPI.transfer(0x01);
  delay(10);
  digitalWrite(8, 1);

  digitalWrite(8, 0);
  SPI.transfer(0x1d + 0x20);
  delay(10);
  SPI.transfer(0x04);
  delay(10);
  digitalWrite(8, 1);
  //Up for DYNPL

  digitalWrite(8, 0);
  SPI.transfer(0x01 + 0x20);
  delay(10);
  SPI.transfer(0x3f);
  delay(10);
  digitalWrite(8, 1);

  digitalWrite(8, 0);
  SPI.transfer(0x02 + 0x20);
  delay(10);
  SPI.transfer(0x03);
  delay(10);
  digitalWrite(8, 1);

  digitalWrite(8, 0);
  SPI.transfer(0x03 + 0x20);
  delay(10);
  SPI.transfer(0x03);
  delay(10);
  digitalWrite(8, 1);

  digitalWrite(8, 0);
  SPI.transfer(0x04 + 0x20);
  delay(10);
  SPI.transfer(0xff);
  delay(10);
  digitalWrite(8, 1);

  digitalWrite(8, 0);
  SPI.transfer(0x05 + 0x20);
  delay(10);
  SPI.transfer(0x4c);
  delay(10);
  digitalWrite(8, 1);

  digitalWrite(8, 0);
  SPI.transfer(0x06 + 0x20);
  delay(10);
  SPI.transfer(0x06);
  delay(10);
  digitalWrite(8, 1);

  digitalWrite(8, 0);
  SPI.transfer(0x0a + 0x20);
  delay(10);
  SPI.transfer(0xaa);
  delay(10);
  SPI.transfer(0xaa);
  delay(10);
  SPI.transfer(0xaa);
  delay(10);
  SPI.transfer(0xaa);
  delay(10);
  SPI.transfer(0xaa);
  delay(10);
  digitalWrite(8, 1);

  digitalWrite(8, 0);
  SPI.transfer(0x10 + 0x20);
  delay(10);
  SPI.transfer(0xaa);
  delay(10);
  SPI.transfer(0xaa);
  delay(10);
  SPI.transfer(0xaa);
  delay(10);
  SPI.transfer(0xaa);
  delay(10);
  SPI.transfer(0xaa);
  delay(10);
  digitalWrite(8, 1);

}

void NRF_startListening() {

  attachInterrupt(digitalPinToInterrupt(2), IRQ, FALLING);

  digitalWrite(7, 1);   //CE High
  Serial.println("Listening started");

}

void NRF_monitorRegisters() {

  for (int i = 0; i < 30; i++) {
    digitalWrite(8, 0);
    SPI.transfer(i);
    delay(10);
    Serial.print(i , HEX);
    Serial.print(" -> ");
    Serial.println(SPI.transfer(0xff), BIN);
    delay(10);
    digitalWrite(8, 1);
  }
  Serial.println("");

}

void setup() {

  Serial.begin(115200);

  NRF_receiverBegin();
  NRF_startListening();
  NRF_monitorRegisters();

}

void loop() {

  /*if (millis() - lastTime > 20000) {
    NRF_monitorRegisters();
    lastTime = millis();
  }*/

}


Arduino Uno Digital to Analog Converter I'm trying to read in an analog signal (a heartbeat) to pin A0 on the Arduino Uno and then convert it to digital. I'm hoping to use the digital signal to make an LED light up every time the voltage of the heartbeat signal goes over 1 volt. This is the code I have right now, but something is wrong because it isn't lighting up the LED.

unsigned int analog0;             // Raw data from A0 ranging from 0 to 1023
unsigned long data_range = 2000;  // Length of time to record data for
double volts;                     // The analog data from A0 converted to volts
int ledPin = 13;
unsigned long start_time;
unsigned long data_time;

void setup() {
  Serial.begin(9600);             // Initialize and set serial port baud rate
  pinMode(ledPin , OUTPUT);
}

void loop() {
  start_time = millis();
  while ((millis() - start_time) < data_range)
  {
    // Record current time of analog acquisition
    data_time = millis();

    // Record analog data on A0
    analog0 = analogRead(0);

    // Convert raw data into voltage
    volts = (analog0 / 1023.0) * 5;

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

    // Slow the rate of data acquisition
    //delay(1);

    if (volts > 1.5){
      digitalWrite(ledPin, HIGH);
      //delay(50);
    }
    else{
      digitalWrite(ledPin, LOW);
    }
  }
}

Try commenting out the serial in your sketch. In my experience serial communication takes time, and I assume you have a short window where the voltage peaks at more than a volt. Or initialize the serial with a stupidly high baud rate.
Edit: even better, you could try this for a faster response time:

void setup(){
  digitalWrite(13,0);
  pinMode(13, OUTPUT);
}

void loop(){
  if(analogRead(A0)>204){ //at ~1V the ADC will read between 204 and 205
    digitalWrite(13,1);
    delay(100);
    digitalWrite(13,0);
  }
}


How to calculate phase shift between two square waveforms with Arduino DUE I have two square wave signals with the same frequency. I want to measure the phase shift between these two signals. There will be a small phase difference between two signals. (0-90 degree) and the frequency will vary in the range 100mHz - 50kHz. I am using an Arduino DUE (ATMEL ATSAM3X8E AU ,ARM)

I tried to use "micros()" for timer functionality to get 2 different times and then calculate the phase shift using the following code:

int led=47,count1=0,count2=0,temp=0;
int i=0,j=0;
float time1[3]={0,0};
float time2[3]={0,0};
float freq1=0,freq2=0;
float period1=0,period2=0;
float ps=0;

void setup()
{
      Serial.begin(9600);
      Serial.println();
       Serial.println();
      pinMode(31,INPUT);
      pinMode(33,INPUT);
      pinMode(led,OUTPUT);
      digitalWrite(led,HIGH);
      noInterrupts();
      attachInterrupt(31,in1,RISING);
      attachInterrupt(33,in2,RISING);
      interrupts();
}

void in1()
{      noInterrupts();
       switch(i){
           case 0 : time1[i]=micros(); i++;  break;
           case 1 : if(j==1){time1[i]=micros(); i++; break;}
       }
       interrupts();
}
void in2()
{      noInterrupts();
       switch(j){
            case 0 : if(i==1){time2[j]=micros(); j++; break;}
            case 1 : if(i==2){time2[j]=micros(); j++; break;}
       }
           if(j==2){
             period1 = (time1[1]-time1[0]);
             period2 = (time2[1]-time2[0]);
             freq1 = 1000.0/period1;
             freq2 = 1000.0/period2;
             ps = (((time2[1]-time1[1])*360.0)s/period1);
          if(freq1==freq2){
          Serial.println("");
          Serial.print("TIME1[0] = ");
          Serial.print(time1[0],6);
          Serial.print("\t TIME1[1] = ");
          Serial.print(time1[1],6);
          Serial.print("\t DEL1 = ");
          Serial.println(time1[1]-time1[0],6);
          Serial.print("TIME2[0] = ");
          Serial.print(time2[0],6);
          Serial.print("\t TIME2[1] = ");
          Serial.print(time2[1],6);
          Serial.print("\t DEL2 = ");
          Serial.println(time2[1]-time2[0],6);
          Serial.print("\t x = ");
          Serial.print(time2[0]-time1[0],6);
          Serial.print("period1(ms) = ");
          Serial.print(period1,6);
          Serial.print("\t period2(ms) = ");
          Serial.println(period2,6);
          Serial.print("freq1 = ");
          Serial.print(freq1,6);
          Serial.print("\t freq2 = ");
          Serial.print(freq2,6);
          Serial.print("\t Phase Shift = ");
          Serial.println(ps,6);
          }
          else {
          i=0;j=0;
          interrupts();
          }
       }
       interrupts();
}
void loop()
{
       ;
}

When I run this code I am not getting any errors, but in high frequency (above 400 Hz) Ihave a problem. When I tested at 0 degrees, this code produced this output:

400 Hz 1.152 degree
500 Hz 1.440 degree
600 Hz 1.727 degree
700 Hz 2.015 degree
800 Hz 2.304 degree
900 Hz 2.592 degree
1 kHz  2.880 degree
2 kHz  5.760 degree
3 kHz  8.649 degree
.
.
.
10 kHz 28.8 degree

Each frequency has lowest degree that this code can calculate.

How can I fix this code? Is it possible to calculate the phase shift between two square wave signals this way?

With 0° you have two inputs triggering interrupts at the same time.  That can't happen.  You can't run two interrupts at the same time, so the second one gets queued up until the first has finished.

With all that serial printing in there there's going to be quite a delay between one interrupt triggering and the next one being allowed to trigger - giving you skewed results.

I would suggest passing your signal through an XOR gate so that you end up with a single small pulse that represents the phase shift between the two signals.


The Ultrasonic sensor just detects the same distance int tPin = 11;
int ePin = 12;
long duration, inches, cm;

void setup()
{
    Serial.begin(9600);
    pinMode(tPin, OUTPUT);
    pinMode(ePin, INPUT);
    pinMode(2, OUTPUT);
}

void loop()
{
    digitalWrite(tPin, LOW);
    delayMicroseconds(5);
    digitalWrite(tPin, HIGH);
    delayMicroseconds(10);
    digitalWrite(tPin, LOW);
    duration = pulseIn(ePin, HIGH);
    cm = (duration / 2) / 29.1;
    inches = (duration / 2) / 74;
    Serial.print(inches);
    Serial.print("in, ");
    Serial.print(cm);
    Serial.print("cm");
    Serial.println();
    delay(100);

    if (inches <= 10) {
        digitalWrite(2, HIGH);
        delay(50);
        digitalWrite(2, LOW);
        delay(50);
    }
    else {
        digitalWrite(2, HIGH);
        delay(500);
        digitalWrite(2, LOW);
        delay(500);
    }
}

The serial print displays the same distance that it first detects. How can I fix this?

First of all you need to make cm, inches and duration float to be more precise. Second, you need to make the delay 2 and 10 microseconds between triggers. Overall, if I'm not wrong you can use the code below without changing your circuit.

int tPin = 11;
int ePin = 12;
float duration, inches, cm; //floating numbers to make the result more precise

void setup()
{
    Serial.begin(9600);
    pinMode(tPin, OUTPUT);
    pinMode(ePin, INPUT);
    pinMode(2, OUTPUT);
}

void loop()
{
    digitalWrite(tPin, LOW);
    delayMicroseconds(2);         //Delay 2 microseconds
    digitalWrite(tPin, HIGH);
    delayMicroseconds(10);        //Delay 10 microseconds
    digitalWrite(tPin, LOW);
    duration = pulseIn(ePin, HIGH);
    cm = duration / 58.2;          //Instead of duration/2/28.1
    inches = cm / 2.54;            //You can use cm that was created before for conversion
    Serial.print(inches);
    Serial.print("in, ");
    Serial.print(cm);
    Serial.print("cm");
    Serial.println();
    delay(100);

    if (inches <= 10) {
        digitalWrite(2, HIGH);
        delay(50);
        digitalWrite(2, LOW);
        delay(50);
    }
    else {
        digitalWrite(2, HIGH);
        delay(500);
        digitalWrite(2, LOW);
        delay(500);
    }
}


How to get version of Arduino board remotely I have multiple Arduino WeMos D1 boards, with a mix of versions bought months apart.  One of these boards is working but I need to update it and I am not sure if it is R1 or R2 (the pinouts are different).  I do not have physical access to it (it is 200+ miles away in an area that is locked down) but I can connect through another device over WiFi.
It has the following included:
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <ESP8266mDNS.h>

#include <WiFiUdp.h>
#include <ArduinoOTA.h>

So, I can even browse to a Webserver to run commands.  How can I add to the code (or even replace it) to return a value that tells me which version the board is?  According to this you can do it with an AT command, but I am not sure how to pass an AT command from the WebServer interface (or any other way).
EDIT: I guess I may have confused the issue with my phrasing.  I can connect to the board and upload a new sketch (using OTA).  My question is, can I put something in a new sketch to determine the board details and upload it.  Once I get that, I can then put in a the actual sketch that I want.

There's nothing you can do with your currently loaded sketch. The board can only do exactly what you have programmed it to do and nothing more.

There are no "AT" commands. They only exist if you load the AT firmware instead of your own firmware
You can't magically make your code do things it wasn't programmed to do1

However the only real differences between the two boards is the version of the ESP8266 module in use: ESP-12E vs ESP-12F, (and the only difference between those modules is the layout of the PCB antenna in order to achieve FCC certification) and the addition of some unpopulated serial and I2C pins.
Aside from that the only other differences are purely cosmetic or of no consequence to your software.
So it really doesn't matter which board you have or which you compile your code for.

1: Unless you can cause some buffer overflow and inject new code into memory to execute, but to do that you'd need to be a l33t h4x0r.

Addendum:
It appears they have two boards, named the same, with different pin arrangements (both sadly very stupidly designed, but there you are).  All I can suggest is compile for one, install it, and see if it works. If it doesn't, then compile for the other and see if that works.
Or compile some special firmware that will probe what you have attached and work out what is attached where - then install and run that.


Software I2C - ATmega8 I am using ATmega8 with 12MHz crystal, on my breadboard. I can use SDA and SCL pins with default arduino library wire.h, and it works. But I want another pins to use I2C protocol.

I tried this library, even on real SDA and SCL pins, but it doesn't work.

I have pull up resistors, I tried with 10k and 4.7k without any success. (But those resistors worked with hardware I2C | TWI)

What am I doing wrong? (All connections is fine, because hardware TWI works but software does not.) Thank you for your help.

(Fuses are ok, because the Atmega won't respond if I remove the crystal oscillator, the LED blinking duration is ok.)

What i want to run (that doesn't work):

#define SDA_PORT PORTC
#define SDA_PIN 4
#define SCL_PORT PORTC
#define SCL_PIN 5

//#define I2C_TIMEOUT 100

#include <SoftI2CMaster.h>

uint8_t ADDR  = 0x68;

void setup(void) {

  Serial.begin(19200);
  Serial.println("Initializing ...");
  i2c_init();

  if (!i2c_start(ADDR | I2C_WRITE)) Serial.println(F("Device does not respond"));
  if (!i2c_write(0x00)) Serial.println(F("Cannot address reg 0"));
  i2c_stop();
}

void loop (void) {
  unsigned int low0, high0, low1, high1;
  unsigned int chan0, chan1;
  unsigned int lux;
  int state1;
  int state2;

  delay(1000);
  i2c_start(ADDR | I2C_WRITE);
  i2c_write(0x00);
  i2c_rep_start(ADDR | I2C_READ);
  low0 = i2c_read(false);
  high0 = i2c_read(false);
  low1 = i2c_read(false);
  high1 = i2c_read(true);
  i2c_stop();
  Serial.print(low0);
}

And the code with hardware TWI that works:

#include "Wire.h"
#define DS3231_I2C_ADDRESS 0x68
// Convert normal decimal numbers to binary coded decimal
byte decToBcd(byte val)
{
  return( (val/10*16) + (val%10) );
}
// Convert binary coded decimal to normal decimal numbers
byte bcdToDec(byte val)
{
  return( (val/16*10) + (val%16) );
}
void setup()
{
  Wire.begin();
  Serial.begin(19200);
  pinMode(13, OUTPUT);
  pinMode(5, INPUT);
}
void readDS3231time(byte *second,
byte *minute,
byte *hour,
byte *dayOfWeek,
byte *dayOfMonth,
byte *month,
byte *year)
{
  Wire.beginTransmission(DS3231_I2C_ADDRESS);
  Wire.write(0); // set DS3231 register pointer to 00h
  Wire.endTransmission();
  Wire.requestFrom(DS3231_I2C_ADDRESS, 7);
  // request seven bytes of data from DS3231 starting from register 00h
  *second = bcdToDec(Wire.read() & 0x7f);
  *minute = bcdToDec(Wire.read());
  *hour = bcdToDec(Wire.read() & 0x3f);
  *dayOfWeek = bcdToDec(Wire.read());
  *dayOfMonth = bcdToDec(Wire.read());
  *month = bcdToDec(Wire.read());
  *year = bcdToDec(Wire.read());
}

Schematic is the same as: https://www.arduino.cc/en/main/standalone.

Except instead of 16MHz, I use a 12MHz and ch210x serial.

Arduino's bootloader works well, I compiled it from source.

OK let me cry till morning...

i was having this issue during day, but the solution was sooo easy

i need to pay attention more ...

  i2c_start(addr | R/W-bit)
  Initiates a transfer to the slave device with the (8-bit) I2C address addr.

what i was trying is to push 7 bit address.

i hope this might help some others.

Thank you for help.


How to make a servo sweep from 0 to 180 on press of a button on PS2 controller? (without delay) I am working on a project that requires the servo to make a complete sweep once on pressing a button say r2 on the pS2 controller. I am using the Arduino Mega 2560,a PS2 controller clone, Bill porter's Ps2x library.

I have figured out a way to do so by adding a delay to the code but when the delay is used I can't use other parts of my project. What should I do?

int pos = 0;    // variable to store the servo position
int button = 2;  // The button will be on Pin 7
void setup()
{
myservo.attach(9);  // attaches the servo on pin 9 to the servo object
pinMode(pos, OUTPUT);
pinMode(button, INPUT);
digitalWrite (button, LOW);
}

void loop()
{
if(ps2x.ButtonPressed(PSB_RED))

for(pos = 0; pos < 90; pos += 90)  // goes from 0 degrees to 90 degrees
{                                  // in steps of  degree
 myservo.write(pos);

}
  if(ps2x.ButtonReleased(PSB_RED))

 for(pos = 90; pos>=90; pos-=90)
 {
myservo.write(pos);
delay(50);                             // waits 50ms for the servo to reach the position

If you already have the code, if you have a good understanding of how it works it shouldn't be too difficult to implement, but you would multitasking it by creating several objects that use a central time value. It should all be here, if you follow them and read them they can explain better than I: https://learn.adafruit.com/multi-tasking-the-arduino-part-1/overview


Can a PC connect to an Arduino for serial communication without installing the entire dev kit? I'd like to send a prototype board to a friend pre-programmed and wired. Ideally they should just need to plug in the USB and connect to it over a serial COM port.

With another laptop I used for testing I had to install the full dev kit, sketch editor and all to get it working.

Can I somehow send just the portion of the kit that provides the COM drivers and not the rest? Is there a prebuilt install for just that portion?

On Windows in C:\Program Files\Arduino there is a folder called drivers, which contains all the drivers for the Arduino boards. I think that's what you are looking for.


serial to parallel and nixie clock I'm going to use this tutorial : https://www.arduino.cc/en/Tutorial/ShiftOut to make a Nixie Clock. I was asking myself if other components that'll be easier to use existed ?

It doesn't get much easier than a shift register :) Why do you think it's a hard-to-use component?

The tutorial you pointed claims to be a Nixie driver, but omits the hardest part about nixies: driving them at 170V. IN12B nixies are easy to come by, they cost about $3 each on ebay, but you may also want to consider http://www.tayloredge.com/storefront/SmartNixie/index.html

I am not affiliated with Tayloredge, I'm just a happy customer.


DC motors not running using PWM and L298N motor driver I'm just beginning to understand Arduino. Please bear with me. I have a collision avoidance car running on Arduino Uno, WB291111 L298N motor driver, SG90 servo, Arduino Shield v5, and HC-SR04 ultrasonic sensor. Also, I have the entire setup running on 8.4v batteries. If I just use HIGH/LOW on the motors, it will run without any problems. But if I use the PWM to run the motors on different speeds, it will NOT run at all. The sensor and servo works, but not the motors.  See my codes below. Let me know if you need further details. Any help is greatly appreciated.

#include <Servo.h>
#include <NewPing.h>

//our L298N control pins
const int enA = 10;
const int in1 = 6;
const int in2 = 7;

const int enB = 9;
const int in3 = 4;
const int in4 = 5;

//sensor pins
#define trig_pin A2
#define echo_pin A1

#define maximum_distance 500
boolean goesForward = false;
int distance = 100;

NewPing sonar(trig_pin, echo_pin, maximum_distance);
unsigned int uS;

#define SERVO_PIN 11
Servo servo_motor;

void setup(){
  Serial.begin(115200);
  pinMode(enA, OUTPUT);
  pinMode(enA, OUTPUT);
  pinMode(in1, OUTPUT);
  pinMode(in2, OUTPUT);
  pinMode(in3, OUTPUT);
  pinMode(in4, OUTPUT);

  servo_motor.attach(SERVO_PIN);

  servo_motor.write(115);
  delay(2000);
  distance = readPing();
  delay(100);
  distance = readPing();
  delay(100);
  distance = readPing();
  delay(100);
  distance = readPing();
  delay(100);
}

void loop(){

  int distanceRight = 0;
  int distanceLeft = 0;
  delay(50);

  if (distance <= 20){
    moveStop();
    delay(300);
    moveBackward();
    delay(200);
    moveStop();
    delay(300);
    distanceRight = lookRight();
    delay(200);
    distanceLeft = lookLeft();
    delay(200);

    if (distance >= distanceLeft){
      turnRight();
      moveStop();
    }
    else{
      turnLeft();
      moveStop();
    }
  }
  else{
    moveForward();
  }
    distance = readPing();
}

int lookRight(){
  Serial.print("Look Right");
  servo_motor.write(50);
  delay(500);
  int distance = readPing();
  delay(100);
  servo_motor.write(115);
  return distance;
}

int lookLeft(){
  Serial.print("Look Left");
  servo_motor.write(170);
  delay(500);
  int distance = readPing();
  delay(100);
  servo_motor.write(115);
  return distance;
  delay(100);
}

int readPing(){
  delay(70);
  int cm = sonar.ping_cm();
  if (cm==0){
    cm=500;
  }
  return cm;

}

void moveStop(){
  Serial.print("Stop");

  digitalWrite(in3, LOW);
  digitalWrite(in1, LOW);
  digitalWrite(in4, LOW);
  digitalWrite(in2, LOW);
}

void moveForward(){

  //if(!goesForward){

    //goesForward=true;

    Serial.print("Forward");

    digitalWrite(in1, HIGH);
    digitalWrite(in3, HIGH);

    digitalWrite(in2, LOW);
    digitalWrite(in4, LOW);

    analogWrite(enA, 250);
    analogWrite(enB, 250);

  //}
}

void moveBackward(){

  //goesForward=false;

  Serial.print("Backward");

  digitalWrite(in2, HIGH);
  digitalWrite(in4, HIGH);

  digitalWrite(in1, LOW);
  digitalWrite(in3, LOW);

}

void turnRight(){
  Serial.print("Right");

  digitalWrite(in1, HIGH);
  digitalWrite(in4, HIGH);

  digitalWrite(in2, LOW);
  digitalWrite(in3, LOW);

  delay(200);

  digitalWrite(in1, HIGH);
  digitalWrite(in3, HIGH);

  digitalWrite(in2, LOW);
  digitalWrite(in4, LOW);

}

void turnLeft(){
  Serial.print("Left");

  digitalWrite(in2, HIGH);
  digitalWrite(in3, HIGH);

  digitalWrite(in1, LOW);
  digitalWrite(in4, LOW);

  delay(200);

  digitalWrite(in1, HIGH);
  digitalWrite(in3, HIGH);

  digitalWrite(in2, LOW);
  digitalWrite(in4, LOW);
}

According to the Servo reference page it's not possible to use Servo library and PWM outputs on the pins 9 and 10.

  On boards other than the Mega, use of the library disables analogWrite() (PWM) functionality on pins 9 and 10, whether or not there is a Servo on those pins.


The code fails to generate the values I want, when both trigger pins 2, 3 are high or low. Why? /*aim of the program is to generate 2 different varying frequency from the
same output which is controlled by 2 triggers*/
void setup()
{
    pinMode(2,INPUT); //setting the trigger pins 2,3
    pinMode(3,INPUT);
    pinMode(6,OUTPUT); //output pin
}

void loop()
{
    if(digitalRead(2)==HIGH && digitalRead(3)==LOW) { //trigger conditions
        infra();
    }
    else if(digitalRead(2)==LOW && digitalRead(3)==HIGH) {
        red();
    }
    else if((digitalRead(2)==HIGH && digitalRead(3)==HIGH) || (digitalRead(2)==LOW && digitalRead(3)==LOW)) {
        Serial.println('help');
    }
}

void infra() //function varies sinosoidaly (working)
{
    float f;

    for(f=16000; f<=20525; f+=4.525) {
        tone(6,f);
    }

    for(f=20525; f>=16000; f=f-4.525) {
        tone(6,f);
    }
}

void red() //function varies sinosoidaly (working)
{
    float p;

    for(p=25000; p<=32071; p+=7.071) {
        tone(6,p);
    }

    for(p=32071; p>=25000; p=p-7.071) {
        tone(6,p);
    }
}

To send anything to serial you need to initialize it first with:

void setup()
{
    Serial.begin(115200);
    //other code
}

And you are using wrong quotes for the string.
They should be double quotes " not single ones '.

Also you could simplify your code, if you removed the third if, since it's just checking the already known state at that point.

You should also read the button state only once, save them into a variable and then just compare those variables.

bool button1_state = digitalRead(2);
bool button2_state = digitalRead(3);
if (button1_state && !button2_state) {
    infra();
}
else if (!button1_state && button2_state) {
    red();
}
else {
    Serial.println("help");
}


strcat gives error when I try to add a char to a char array I have

char c;

where

int bt_available = Serial2.available();
if (bt_available) {
  c = Serial2.read();
}

and later in the code I try to

strcat(some_char_array, c);

and it gives me this error

  initializing argument 2 of 'char* strcat(char*, const char*)' [-fpermissive]
  error: invalid conversion from 'char' to 'const char*' [-fpermissive]

My best guess why the error appears would be that strcat can only accept strings and char arrays, but not single characters, so a solution I can think of would be to create a char array like char test[1] where test[1] = '\0' and then test[0] = c but I'm not sure if that's the best way to go about the problem and if that's a solution. Does 'const char*' mean 'char[]'?

P.S I read Majenko's blog thingy and I'm turning all Strings to char arrays and it's a bit of suffering :P

A char is a single character. A char * and a char[] are both arrays of characters (more correctly char * is a pointer to an array of characters).

strcat expects two arrays or pointers to arrays of characters. If you want to add a single character you can either fool the compiler into thinking that the character is an array of characters of size 1 (but it lacks the required NULL termination) or manually manipulate the target array.

For the former you could use strncat and casting:

strcat(some_char_array, &c, 1);

That gives you a pointer to the character, which is as far as the compiler is concerned, indistinguishable to a pointer to an array of characters. You use the "n" variant of strcat  to limit it  to just one character (plus an added NULL character) so it doesn't rely on the missing NULL termination.

For the second you could do:

int n = strlen(some_char_array);
some_char_array[n] = c;
some_char_array[n+1] = 0;

That just sets the Nth character in the target array to whatever is in c, then adds a new NULL termination character to the end.


How to drive SPI MAX7219 7-segment led module using MCP23S17 extender I have used Nick Gammon's (MAX7219) and (bitBangedSPI) libraries to drive SPI 7-segment 8 digit led modules successfully from the Arduino Uno.  I would like to extend the number of Slave Select (CS) choices by using the MCP23S17 chip.  The Mcp23s17 libraries to use might be https://github.com/dreamcat4/Mcp23s17 or https://github.com/MajenkoLibraries/MCP23S17.  I have found the stackExchange entry How do you use SPI on an Arduino? to be helpful and this entry to be helpful http://www.ermicro.com/blog/?p=1050, but all the examples just turn on LED lights, not digits of 7-segment led modules.

I realize I might have to modify the MAX7219 and bitBangedSPI libraries where the digitalWrite command is used.  However, I'm not sure how to modify or drive these 7-segement modules using the MCP23S17 chip.

A skeleton script to display PI selected on pin 6 on the Uno and address 0x0 of the MCP23S17 is shown below.  I would like to choose which pinout to utilize as well but am not sure how this would be coded.

#include <SPI.h>
#include <bitBangedSPI.h>
#include <MAX7219.h>
// Mcp23s17 library available from https://github.com/dreamcat4/Mcp23s17
#include <Mcp23s17.h>

// Wire up the SPI Interface common lines:
// #define SPI_MOSI             7 //arduino   <->   SPI Master Out Slave In   -> SI  (Pin 13 on MCP23S17 DIP)
// #define SPI_MISO   not used 12 //arduino   <->   SPI Master In Slave Out   -> SO  (Pin 14 on MCP23S17 DIP)
// #define SPI_CLOCK            8 //arduino   <->   SPI Slave Clock Input     -> SCK (Pin 12 on MCP23S17 DIP)

// Then choose any other free pin as the Slave Select (pin 10 if the default but doesn't have to be)
#define MCP23S17_SLAVE_SELECT_PIN  6 //arduino   <->   SPI Slave Select           -> CS  (Pin 11 on MCP23S17 DIP)
// MULTIPLE DEVICES
// Up to 8 MCP23S17 devices can share the same SPI bus and slave select pins.
// Assign each chip a unique 3-bit device address (by setting the A2,A1,A0 pins)
// Then below, device address is optional 2nd parameter to the constructor fn...
// MCP23S17 Mcp23s17_0 = MCP23S17(MCP23S17_SLAVE_SELECT_PIN,0x0);
// ...
// MCP23S17 Mcp23s17_7 = MCP23S17(MCP23S17_SLAVE_SELECT_PIN,0x7);

// SINGLE DEVICE
// Instantiate a single Mcp23s17 object
MCP23S17 Mcp23s17_0 = MCP23S17(MCP23S17_SLAVE_SELECT_PIN,0x0);
const byte chips = 1;
static char outputBuffer[20]; // outputBuffer[] likely 2x the size it needs to be.

 // 1 chip, bit banged SPI on pins 6, 7, 8

MAX7219 display(chips, 6, 7, 8);  // Chips / LOAD / DIN / CLK
void setup()
{
    // Set all pins to be outputs (by default they are all inputs)
    Mcp23s17_0.pinMode(OUTPUT);

    display.begin();
    display.setIntensity(1);
    float pi = PI;
    dtostrf(pi, 7, 7, outputBuffer);
    display.sendString(outputBuffer);

}  // end of setup

void loop() { }

An example of the 8-digit 7-segment display.  They are available on Amazon, Ebay, AliExpress etc. This one has 0.33 inch digits; other modules are 0.56 inch digits.

I'm not 100% on what you want to do but I have used both the chips you seem to want to do it with.

The MAX7219 can control 8 7Segment displays.
I don't remember it being an SPI device, you just set the pattern you want in the registers and off it goes.  (It could be that is used such a high level abstraction that I didn't realise it was SPI)

The IOX chip you are referring to is quite similar in behaviour, you setup the registers and away it goes.

On the surface it appears you can do what you want, but I suspect you will hit timing issues unless you want very static displays (maybe < 1FPS).  The time it takes you to establish the correct settings on the IOX chips will be the limiting factor.

You might want to look at the I2C version of the IOX which will require just 2 pins to connect to up to 7 ICs.

Alternatively use a network of microprocessors to each drive the maximum number of MAX7219s that they can, such as Nanos, ESP8266-12/NodeMCU, etc.


How to get the free/used space on a SD card and transmit it I'm using this block of code to read and sum up the bytes of all the text files I have on an SD card:

long get_sd_memory_taken() {
  File dir = SD.open("/");
  long sd_memory_taken;
  int c = 0;
  while (true) {
    File entry = dir.openNextFile();
    if (!entry) {
      return sd_memory_taken;
      break;
    }
    if(strcmp(entry.name(), "SYSTEM~1") == 0) {
      continue;
    }
    if(c > 15) {
      tft.println(entry.name());
      tft.println(entry.size());
    }
    sd_memory_taken += entry.size();
    entry.close();
    c++;
  }
}

The SD card is 8GB so the number won't be larger than 8,589,934,592. The function get_sd_memory_taken() returns the number so it can be send to a phone using Bluetooth. I just checked that long can hold max 2,147,483,647, so if the SD card is filled more than that, I suppose errors are gonna appear. How can I prevent this? I was thinking of maybe using a double and put the comma maybe 5 digits to the left and send that or maybe divide the number into 10 smaller longs and send them to the phone separately. I think the former method is better but I'm not sure if it'll work. What's the best way to go about this problem where I'm trying to use as less memory as possible?

As SD.h includes

  #include "utility/SdFat.h"
  #include "utility/SdFatUtil.h"

or if you use the SDfat library than this function is more efficient than going all over the place:

#include <SdFat.h>

SdFat SD;

void ShowFreeSpace() {
  // Calculate free space (volume free clusters * blocks per clusters / 2)
  long lFreeKB = SD.vol()->freeClusterCount();
  lFreeKB *= SD.vol()->blocksPerCluster()/2;

  // Display free space
  Serial.print("Free space: ");
  Serial.print(lFreeKB);
  Serial.println(" KB");
}


ISP Programmer with Serial and 5v/3.3v power I currently use a Pololu USB AVR Programmer v2.1 for programming 328p chips and I really like it. The ability to have ISP and Serial in one physical device, enumerating as two separate COM ports on the PC, the programmer powering the circuit at 3.3v, with the programmers windows GUI interface to set voltages, programming frequency and give feedback on the programming when things go wrong, is all brilliant.
However, many of my circuits either have a power requirement higher than that on the Pololu (80mA), or to much capacitance (33uF) so that the power surge on connection is too much for the Pololu and it resets.  The reset disconnects my serial debugger, disconnects the Pololu GUI, and sometimes does not come back on at all due to the startup current draw.
I am looking for suggestions for an alternative device, or way of stopping the brown out on power up?
Thanks very much
Kevin

How about, connecting a tiny battery across the 3.3v output of the Pololu.  Lets assume a 3.7v LiPo, charged to 3.3v.
When the battery is connected at 3.3v, no current will flow.
When my device to be programmed is connected it will draw a spike of current, which will start to take the Pololu below 3.3v, but then the LiPo will start supplying current and stop the Pololu voltage getting dragged down and browning out.
The LiPo will then be slightly below 3.3v, so will get a Constant Voltage charge back to 3.3v.
Two potential issues I can see:

When the Pololu is disconnected from the USB will it be being 'back powered' by the LiPo?

When in CV charge mode, the only current limiting will be internal resistance of the Pololu output / LiPo cell, probably not an issue in practice due to the voltage drop being very small.

I know it is a hack, but thoughts welcomed.
Cheers
Kev


Write faster on AT24C32 I'm using AT24C32 EEPROM chip from ATmel. I found code that will write and read bytes from chip.
Code writes and reads bytes correctly and without any problem.

But I have to write few 8-byte values often(every 10-15 seconds). I did "cut" those variables to 48 bit(so 6-byte variable) and with that I speeded up saving but it's still slow.

Is there any chance to speed up saving proccess? Code is below

void EEPROMClass::write48(int16_t address, uint64_t value)
{
    uint8_t byteValue = (value & 0xFF);
    write8(address, byteValue);

    byteValue = ((value >> 8) & 0xFF);
    write8(address + 1, byteValue);

    byteValue = ((value >> 16) & 0xFF);
    write8(address + 2, byteValue);

    byteValue = ((value >> 24) & 0xFF);
    write8(address + 3, byteValue);

    byteValue = ((value >> 32) & 0xFF);
    write8(address + 4, byteValue);

    byteValue = ((value >> 40) & 0xFF);
    write8(address + 5, byteValue);
}

void EEPROMClass::write8(int16_t const address, uint8_t const value)
{
    Wire.beginTransmission(AT24C32);

    Wire.write(highAddressByte(address));
    Wire.write(lowAddressByte(address));

    Wire.write(value);
    delay(2);
    Wire.endTransmission();
}

delay of 2ms is required otherwise EEPROM will write different value. Code has 4 "6-byte" variables(total of 24 bytes). Every byte is minimum 2ms, so total time to save only "6-byte" variables is 48ms(round to 50ms). That is too slow for me. How to speed up write function?

after writing a value to EEPROM, and terminating the I2C connection with a STOP, the EEPROM enters a self writing mode to write what you have sent to it, to it's internal memory. (you don't actually write the values to the memory section; you write them to a buffer, and then the internal controller writes them to its memory section).

this "self writing mode" takes about 5ms, and you cant do nothing about it. but you can use "page writing" instead of byte writing. that 32K model, has a 32 bytes page buffer. you have to send all the bytes (as long as they are under 32 bytes) at once in one I2C transaction. this time, the chip fills its page buffer and then after a STOP, writes it all at once on its memory. in your code, you just write one byte in your buffer each time in a single transaction. like sending a bus with just one passenger at a time.

remember in this mode, you only set the address of the first byte. the next bytes automatically settle in the next addresses.


How do I reset my libraries back to original condition? How do I reset my arduino installation back to its original state? i.e., no extra downloaded libraries, etc.  If I delete Documents/Arduino/libraries is there any other state that needs to be cleaned up?

Delete the Documents -> Arduino -> Libraries to remove all your libraries.
Delete the User -> AppData -> Local -> Arduino15 folder to remove all the preferences.
Uninstall Arduino IDE.
Install a fresh one.