title: 5V pin output on arduino

text:
# Question
Title: 5V pin output on arduino
Sorry for the newbie question (just started learning electronics).

I just saw a tutorial that says that the 5V output pin on the Arduino delivers more amps (if needed) when connecting more voltage to the board (connecting to the 9 - 12V instead of 5V). Does that mean that the 5V pin then delivers more than 5V as well?

# Answer
Time for a crash course in electronics and power:

The 5V pin only ever provides 5V. That's why it's the "5V" pin. (assuming, of course, that you give the board *more* than 5V).

In simple linear electronics you have three values:

* The voltage
* The current
* The load

Generally two of the three are either "fixed" or "known" and the third changes depending on the other two. For simple resistive circuits (where the load is a simple resistor) this relationship is Ohm's Law.

* If the voltage is fixed, and
* If the load changes, then
* The current will also change to keep the relationship stable.

A "power supply" (any device which provides power to some other device) generally has two parameters: Voltage and Current. One of those is always fixed. The other is always variable, and quoted as a maximum that the supply can give.

For the Arduino's 5V pin the parameters are:

* Voltage: 5V
* Current: 800mA Maximum

That means that the 5V pin has a fixed voltage of 5V, but the current is free to change depending on the load *up to a maximum of 800mA* (or a lower limit if you are providing the input power from a source with a lower current. There is also heat to consider with the Arduino - see below).

The two values, voltage and current, combine together to give the "power" of the power supply, through simple multiplication. So the Arduino's 5V pin is 5V × 0.8A = 4 watts maximum.

When you provide power to the Arduino through the barrel jack it first goes through a *linear voltage regulator*. This is the device which takes the incoming voltage and reduces it to 5V. Since energy can neither be created nor destroyed it does that reduction in energy by converting some of it to heat.

Say you connect something up that needs 100mA and you plug in a 9V power supply to the board. Let's also assume that the Arduino itself needs 50mA (I like nice round numbers).

* That's 150mA in total for the "load".
* The incoming voltage is 9V
* The outgoing voltage is 5V

The power of the input is thus 9V × 0.15A = 1.35W The power of the output is then 5V × 0.15A = 0.75W

The power difference is 0.6W

That 0.6W is converted from electrical energy to heat energy by the voltage regulator and "thrown away".

So the "heavier" your load (the more current you demand from the 5V pin) the greater the heat that is generated by the voltage regulator.

When the regulator gets too hot one of two things happen:

1. A good quality regulator will shut down and you will lose power to the board
2. A cheap Chinese regulator will likely "fail short" and feed your 9V direct into the Arduino causing components to release their Magic Smoke™ and stop working
> 5 votes

---
Tags: arduino-uno, electronics
---


title: Timing 12 relays

text:
# Question
Title: Timing 12 relays
I need a simple code to turn on 12 outputs one after another 2 seconds apart. A pushbutton will initiate this and the outputs will stay on for 3 minutes at which time all outputs will turn off awaiting the pushbutton input

So far:

```
Void setup
pinMode (10,output);
PinMode (11,output);
PinMode (12,output);

Void loop
delay(100);
digitalWrite (10,HIGH);
delay (2000);
digitalWrite(11,HIGH);
delay(2000)
digitalWrite(12,HIGH);

delay(180000);
digitalWrite (11,LOW);
digitalWrite (12,LOW);
digitalWrite (10,LOW);
exit(0);

```

Push remote reset button to restart.

Only tried 3 outputs for now and haven’t tried “Crossroads” code yet but I will.

# Answer
> 3 votes
Don't use Delay. CrossRoads provided a decent starting point for your code, but his code is based on `delay()`, which is a dead end.

Instead of delay, use a bool `running` to track whether you're relay sequence is running or not. Also have an `unsigned long` `startTime`, and an array of bools to track if each relay is on or off.

If !running, check the button. If the button is pressed, set running to true, and set startTime to `millis()`.

Then, use millis() to figure out where you are in the sequence. Calculate `(millis()-startTime)/1000/num_relays`. Let's call it `relayIndex`.

When `relayIndex` is less than `num_relays - 1`, check the bool for that relay, and if it's off, set it on and turn on that relay. When `relayIndex` reaches `num_relays-1`, you're done turning on relays. Now it's time to wait for 3 minutes to go by. After 3 minutes, turn off all the relays and relay bools, and set `running=false`. Have the reset button do the same thing.

## EDIT

Also note that controlling relays from an Arduino (or from other solid state devices for that matter) requires special hardware and precautions. You should probably use a "digital" relay (something like this, or better yet **this** 6 channel relay) that isolates the Arduino control line from the high current needed to drive the relay.

Failing that, you should build a control circuit from a MOSFET transistor and a "flyback diode". Without flyback diodes, the inductive coils on your relays emit "**back EMF**" which will likely fry your transistors (and possibly the Arduino)

# Answer
> 0 votes
Simple code:

```
byte buttonPin = 2;
byte relayPins [] = {3,4,5,6,7,8,9,10,11,12,13,14,};
byte x;

void setup() {
  pinMode(buttonPin, INPUT_PULLUP);
  for (x=0; x<12; x=x+1) {
    pinMode(relayPins[x], OUTPUT);
  }
}

void loop() {
  if (digitalRead(buttonPin) == LOW) {
    for (x=0; x<12; x=x+1) {
      digitalWrite(relayPins[x], HIGH); // drive base of NPN or N-MOSFET to sink current
      delay(2000);
    }
    delay(180000); // dumb 3 minute delay
    for (x=0; x<12; x=x+1) {
      digitalWrite(relayPins[x], LOW);
    }
  }
}

```

And of course, supporting hardware to drive relay coils.

---
Tags: programming
---


# Question
Title: My push button code doesn't work properly
I'm using an OLED display connected to a push button. I am trying to get my display to show two different values independently by using the push button to switch between them. Here is a snap of my code from the loop function:

```
    if (buttonState == HIGH) {
    x=x+1;
  }
  if (x == 1) {
  display.setTextColor(WHITE);
  display.setCursor(0, 0);
  display.setTextSize(2);
  display.print(T);
  display.print(" degree");
  display.display();
  display.print(x);

}
    else if (x == 2) {
  display.setTextColor(WHITE);
  display.setCursor(0, 0);
  display.setTextSize(2);
  display.print(perventage);
  display.print(" %");
  display.display();
  display.print(x);
}
    else  {
      x=1;
      }

  delay(10);
}

```

x is defined as 1 initially out side the loop. What happens is that when the circuit is turned on, the screen displays the value of T then what should happen is when I push the button it switches to the second value which is percentage, and I push again to go back to T. My issue is that the Arduino doesn't response to the push button all of the time sometimes it takes 1 click and other times it takes 6 or 8 fast clicks to switch between them and it doesn't stick to a specific number of pushes to switch. What would you suggest me to change to fix it.

Edit: here is pic of my wiring diagram

# Answer
One core problem is that you have a simple "If the button is HIGH then cycle through the numbers". The longer you hold the button the more times it will cycle through the numbers. It's pure 50/50 chance that you happen to release the button on a different number to the one it started on.

Instead you need to look for a *change* in the state of the button. Has it changed from LOW to HIGH:

```
static uint8_t oldState = LOW;

uint8_t buttonState = digitalRead(BUTTON_PIN);
if (buttonState != oldState) {
    oldState = buttonState;

    if (buttonState == HIGH) {
        // This only runs once at the moment of pressing
        // the button - not continuously while you're
        // holding the button in.
        // Cycle through your displays here.
    }
}

```
> 0 votes

# Answer
You are reading the raw button state without debouncing it, so you may be getting 2 (or 4, or ...) pulses so quickly - off the same button-push - that the display or your eye can't respond that quickly. Here is Nick Gammon's tutorial on switches and buttons, including debouncing.

Also make sure you use a pull-down resistor on the button input-pin. Floating inputs are noise and will give you a lot of false signals.
> 1 votes

---
Tags: arduino-ide, arduino-nano, code-review
---


# Question
Title: My 12V DC Vending Machine motor rotates 1 extra 360 degree rotation sometimes. What could be the reasons?
have main board which has motor control circuit and has row and column to control the row and column of the vending machine.

I have made changes in motor in two ways:

A. I have attached an image for circuit diagram

In this design I have some pros and cons

PROS: 1. It stops at its home position after one rotation 2. It detects row and column of the machine

CONS: 1. Sometime it does not stop at its home position or take more than 1 rotation

B. I have attached an image of other diagram

In this design also I have some pros and cons

PROS: 1. It stops perfectly at its home position after one rotation.

CONS: 1. It does not detect ROW

Please suggest What should I follow and what should I made changes in the circuit.

Here is the video

https://drive.google.com/open?id=1N7ItjeU84JiDAOquAD6SGHkVWufDT40K

https://drive.google.com/open?id=1VX9yncrm6pcr1IBQsNvVZ1yR0UMflJKA

# Answer
> "It rotates little bit forward like 10% extra with 3.1 sec delay,"
>
> "I just want to rotate the motor from the home location to the home location when I give signal one time. But i do not know what time delay should I use?"

More than 2.0 and less than 3.1! If 3.1 sec gives 110% rotation, then you need (100/110)\*3.1 = 2.818sec to get 100%.

I realize that your 10% extra is an estimate and not accurate to 3 decimals, but I'd use 2.82 as a starting point and tweak it up or down until you get the amount of rotation you want.

Remember that timing a motor to get distance will inherently be inaccurate due to inconsistencies in the motor acceleration rate and rotation speeds, due to variations in its temperature and the power supply voltage, and load, but this should get you started. For long term accuracy, i.e., if you need it to always come back to a fixed position, you'll need some position feedback, which may be as simple as flag on the motor shaft interrupting a photocell. And even that will have *some* degree of inconsistency due to coasting speed when you shut the power off, but at least those error won't accumulate.

Update:

> 2.82, My motor rotates 10% less every time and change its location in every rotation

Right - 2.82 was a first approximation. If that is too small, try splitting the difference between 2.81 and 3.1. If that ends up too small, then split the difference between it and 3.1; or if it was too big, try splitting the difference between 2.1 and it. Do that a few more times until you have an acceptably close value.

Then read what I said about accumulating errors. The Arduino doesn't ever know what the motor position is so it can't correct for any overshoot or undershoot. If you need accuracy and repeatability, you'll have to add some kind of position sensing, or switch to using a stepper motor and drive the number of steps that makes one full rotation (and it would still have to be started from a known position).
> 1 votes

---
Tags: arduino-uno, motor
---


title: power consumption of esp32

text:
# Question
Title: power consumption of esp32
I'm currently working on an IOT project with my esp32, ill need it to run on batteries, I will only be needing "active mode" with wifi once per hour to upload some data to a database and then go back to deep sleep (need to save data cant use hibernation).

THIS website explain pretty well how much energy the esp needs, but it says e.g. 30mA - 60mA, but on batteries it says mAh, so is the mA just mAh or how do I calculate the power usage?

.

ps.

currently, I'm thinking of using 2 cr2032 batteries, good recommendations on batteries are welcome

# Answer
> 4 votes
There's a number of things to consider when choosing batteries.

First is the capacity. In broad terms, the capacity is, mAh, means "This battery can supply X mA for one hour". So a battery of 1000mAh could supply around 1A (1000mA) for one hour before it goes flat. Simply divide the mAh by your device's mA and you get the time it will run for before it goes flat. So a 50mA device would run for about (1000 / 50) 20 hours before running flat. That is only a "ball park" figure though, since the capacity is somewhat dependent on the amount of current you draw.

Then there is the question of the internal resistance of the battery. This determines the maximum current that you can draw from the battery before the voltage drops below a usable level. Different battery chemistries have different internal resistances.

Small button cells like the CR2032 have a high internal resistance and a low capacity. A typical cheap CR2032 has around 200mAh capacity. At 50mA that would last 4 hours. But drawing 50mA from a CR2032 is not really on. Looking at the graphs in the datasheet linked to above you can infer that, with a nominal voltage of 3V, with a 1kΩ load the output drops to 2.6V. That means that 1kΩ is drawing (2.6/1000) 0.0026A (2.6mA). The internal resistance is dropping (3 - 2.6) 0.4V, therefore the internal resistance must be (0.4 / 0.0026) 154Ω.

Drawing 50mA from the battery would mean the internal resistance would drop (154 * 0.05) 7V. Since you can't get below 3V, that means the battery simply can't support that kind of current drain. Indeed, in the datasheet I link to the "Standard Current Drain" (the current it's rated for as "normal" usage) is a mere 0.1mA.

So to work out what battery you need, you want:

* The average current draw over the period of an hour
* The peak current draw the device will draw
* The length of time you need the device to run for between battery changes / recharges

For the ESP32 the current can peak at hundreds of mA depending on what you are doing (WiFi uses a lot of power in short bursts). The average will be based on the ratio of the "running" time to the "sleeping" time, and the current draw for both those states.

---
Tags: power, battery, esp32
---


# Question
Title: Not able to find right library for MPU9250
I am using an Arduino Uno and learning to use the motion sensor. Currently I was not able to find the library which looks simple and would like to get your suggestion. I found this https://github.com/hideakitai/MPU9250 library to be simple but don't know how to use it.

For example, take this code:-

```
#include "MPU9250.h"

MPU9250 mpu;

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

    Wire.begin();

    delay(2000);
    mpu.setup();
}

void loop()
{
    static uint32_t prev_ms = millis();
    if ((millis() - prev_ms) > 16)
    {
        mpu.update();
        mpu.print();

        Serial.print("roll  (x-forward (north)) : ");
        Serial.println(mpu.getRoll());
        Serial.print("pitch (y-right (east))    : ");
        Serial.println(mpu.getPitch());
        Serial.print("yaw   (z-down (down))     : ");
        Serial.println(mpu.getYaw());

        prev_ms = millis();
    }
}

```

Some values are not defined here, like registration code and input pins. I am not used to reading the documentation code so might need help in that.

# Answer
> 3 votes
In the Arduino IDE, click on SKETCH \> INCLUDE LIBRARY \> MANAGE LIBRARIES.

Then, search for 9250, select the SparkFun one, and click INSTALL.

Finally, from the examples, choose the MPU9250BasicAHRS\_I2C.

---
Tags: sensors, library, mpu6050, imu
---


# Question
Title: I2C connection freezes Master if Slave disconnects
I am using I2C to successfully request critical data from a Slave device (I **have** to use requestFrom() in the Master) but if, for some reason, the power disconnects from the Slave device then the Master freezes altogether. I didn't realise I2C was so problematic in this regard and I have been a number of weeks trying all types of alternative setups to try and avoid this situation. I can't seem to find a way for example, to simply check if a Wire() connection exists before requesting data and freezing everything. Both devices are Arduino Uno r3. Any ideas I may not have tried yet? Any way to send a single value to the Master and update it every 30 secs would do. Actually the data comes from a capacitive sensor, so would it be possible to just have both arduinos read from the same sensor?

In response to Nick Gammons suggestions (below): I have edited the examples you gave to try and fit in with what I am trying to achieve. I would like to do the following. Catch a situation where the Master (Arduino Yun Shield) cannot communicate with the Slave ( Arduino r3 - with sensor) due to its power supply and/or sensor reading failing. In other words, an Arduino monitoring another Arduino. Here is my edited versions, however I am still not able to catch the "else" condition of the Slave being unreachable:

SLAVE

```
#include <Wire.h>

const byte MY_ADDRESS = 42;

// various commands we might get

enum {
    CMD_ID = 1,
    CMD_READ_A0  = 2
    };

char command;

void setup()
  {
  command = 0;
  pinMode (A0, INPUT);

  Wire.begin (MY_ADDRESS);
  Wire.onReceive (receiveEvent);  // interrupt handler for incoming  messages
  Wire.onRequest (requestEvent);  // interrupt handler for when data is wanted

  }  // end of setup

void loop()
  {
  // all done by interrupts
  }  // end of loop

void receiveEvent (int howMany)
  {
  command = Wire.read ();  // remember command for when we get request
  } // end of receiveEvent

void sendSensor (const byte which)
  {
  //int val = analogRead (which);
  int val = 125;//test only
  byte buf [2];
    buf [0] = val >> 8;
    buf [1] = val & 0xFF;
    Wire.write (buf, 2);
  }

void requestEvent ()
  {
  switch (command)
     {
     case CMD_ID:      Wire.write (0x55); break;   // send our ID
     case CMD_READ_A0: sendSensor (A0); break;  // send A0 value
     }
  }

```

MASTER

```
#include <Process.h>
#include <I2C.h>
#include <Bridge.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C  lcd(0x27, 16, 2);

const int SLAVE_ADDRESS = 42;

// various commands we might send
enum {
  CMD_ID = 1,
  CMD_READ_A0  = 2,
};

void setup ()
{
  Bridge.begin();
  Console.begin();
  //while (!Console);
  I2c.begin ();
  I2c.timeOut(100);  // milliseconds

  lcd.init();
  lcd.backlight();
}

void loop()
{
  int value = getA0();
  Console.print("A0 value:");
  Console.println(value);
  lcd.setCursor(0, 0);
  lcd.print("A0 value:");
  lcd.print(value);//displays first '0' reading then freezes code
  delay (5000);
}

int getA0() {
  if (I2c.write (SLAVE_ADDRESS, CMD_READ_A0) == 0) {
    byte buf [2];
    int val;
    if (I2c.read (SLAVE_ADDRESS, sizeof buf, buf) == 0)
   {
      val = buf [0] << 8 | buf [1];
      return val;
    }
    else {
      return 0;
    }
  }
  else {
    return 0;
  }
  delay(500);
}

```

# Answer
> 3 votes
There is code inside the standard library that loops waiting for certain interrupts to complete transmission. If the transmission fails in the middle it can hang.

See my page about I2C. On that page I mention that there is an alternative library. That is written a bit differently so it times out if the transmission doesn't complete in time. An alternative download to the library is here - I2C\_Rev5.zip - 6.6 KB.

---

As hinted by KIIV in a comment, maybe you don't have pull-up resistors. Make sure that you have pull-up resistors from both SDA and SCL to the +5V line. A reasonable value would be 4.7k (each).

---

## Example code

> would like a few more examples to show a similar setup to replace my current requestFrom

Borrowed from my page about I2C I am using the same slave code as on that page.

### Slave

```
#include <Wire.h>

const byte MY_ADDRESS = 42;

// various commands we might get

enum {
    CMD_ID = 1,
    CMD_READ_A0  = 2,
    CMD_READ_D8 = 3
    };

char command;

void setup()
  {
  command = 0;

  pinMode (8, INPUT_PULLUP);
  pinMode (A0, INPUT);

  Wire.begin (MY_ADDRESS);
  Wire.onReceive (receiveEvent);  // interrupt handler for incoming messages
  Wire.onRequest (requestEvent);  // interrupt handler for when data is wanted

  }  // end of setup

void loop()
  {
  // all done by interrupts
  }  // end of loop

void receiveEvent (int howMany)
  {
  command = Wire.read ();  // remember command for when we get request
  } // end of receiveEvent

void sendSensor (const byte which)
  {
  int val = analogRead (which);
  byte buf [2];

    buf [0] = val >> 8;
    buf [1] = val & 0xFF;
    Wire.write (buf, 2);
  }  // end of sendSensor

void requestEvent ()
  {
  switch (command)
     {
     case CMD_ID:      Wire.write (0x55); break;   // send our ID
     case CMD_READ_A0: sendSensor (A0); break;  // send A0 value
     case CMD_READ_D8: Wire.write (digitalRead (8)); break;   // send D8 value

     }  // end of switch

  }  // end of requestEvent

```

The above code responds to requests to send one of:

* Its ID (0x55)
* An analog reading (A0)
* A digital reading (D8)

---

### Master using Wire library

The master from my page was this:

```
#include <Wire.h>

const int SLAVE_ADDRESS = 42;

// various commands we might send
enum {
    CMD_ID = 1,
    CMD_READ_A0  = 2,
    CMD_READ_D8 = 3
    };

void sendCommand (const byte cmd, const int responseSize)
  {
  Wire.beginTransmission (SLAVE_ADDRESS);
  Wire.write (cmd);
  Wire.endTransmission ();

  Wire.requestFrom (SLAVE_ADDRESS, responseSize);
  }  // end of sendCommand

void setup ()
  {
  Wire.begin ();
  Serial.begin (115200);  // start serial for output

  sendCommand (CMD_ID, 1);

  if (Wire.available ())
    {
    Serial.print ("Slave is ID: ");
    Serial.println (Wire.read (), DEC);
    }
  else
    Serial.println ("No response to ID request");

  }  // end of setup

void loop()
  {
  int val;

  sendCommand (CMD_READ_A0, 2);
  val = Wire.read ();
  val <<= 8;
  val |= Wire.read ();
  Serial.print ("Value of A0: ");
  Serial.println (val, DEC);

  sendCommand (CMD_READ_D8, 1);
  val = Wire.read ();
  Serial.print ("Value of D8: ");
  Serial.println (val, DEC);

  delay (500);
  }  // end of loop

```

---

### Master using I2C library

The `beginTransmission()` ... `write()` ... `endTransmission()` have been replaced by simply `write()` and the `requestFrom()` by `read()` like this:

```
#include <I2C.h>

const int SLAVE_ADDRESS = 42;

// various commands we might send
enum {
    CMD_ID = 1,
    CMD_READ_A0  = 2,
    CMD_READ_D8 = 3
    };

void setup ()
  {
  I2c.begin ();
  I2c.timeOut(100);  // milliseconds
  Serial.begin (115200);  // start serial for output

  I2c.write (SLAVE_ADDRESS, CMD_ID);
  byte id;

  if (I2c.read (SLAVE_ADDRESS, sizeof id, &id) == 0)
    {
    Serial.print ("Slave is ID: ");
    Serial.println (id, DEC);
    }
  else
    Serial.println ("No response to ID request");

  }  // end of setup

void loop()
  {

  I2c.write (SLAVE_ADDRESS, CMD_READ_A0);

  byte buf [2];
  int val;
  if (I2c.read (SLAVE_ADDRESS, sizeof buf, buf) == 0)
    {
    val = buf [0] << 8 | buf [1];
    Serial.print ("Value of A0: ");
    Serial.println (val, DEC);
    }
  else
    Serial.println ("No response to CMD_READ_A0 request");

  I2c.write (SLAVE_ADDRESS, CMD_READ_D8);
  uint8_t digitalVal;
  if (I2c.read (SLAVE_ADDRESS, sizeof digitalVal, &digitalVal) == 0)
    {
    Serial.print ("Value of D8: ");
    Serial.println (digitalVal, DEC);
    }
  else
    Serial.println ("No response to CMD_READ_D8 request");

  delay (500);
  }  // end of loop

```

# Answer
> 2 votes
I ran into almost the same problem in an educational context. If the I2C bus has a line stuck low, the program hangs in the wire library. In my application everything is soldered together, but not always properly, so I can get by with a single test at startup. Before invoking Wire.begin. For the OP's issue, they will want to use this every time they restart communication after an idle period.

This is part of a device's self test on power up. When one thing is assembled wrong, frequently many things are wrong, so we want to continue on and test everything else. Then the user can fix all of the issues at once. Or perhaps they haven't even built the I2C part of the circuit yet, and they want to test other hardware. In any case, hanging is not an informative way of reporting an error.

```
// Written by Paul Haas for public use. This is public domain code.
// But please don't sue me if it doesn't work.
bool Would_I2C_Hang(int SDAPin, int SCLPin) {
  bool wouldHang = false;
  pinMode(SDAPin,INPUT);
  pinMode(SCLPin,INPUT);
  if ( digitalRead(SDAPin) != 1 ) {
    Serial.println("SDA pin is low");
    wouldHang = true;
  }
  if ( digitalRead(SCLPin) != 1 ) {
    Serial.println("SCL pin is low");
    wouldHang = true;
  }
  return wouldHang;
}

void setup() {
  Serial.begin(115200);
  for(int i=5;i>0;i--) {
    Serial.print(i);
    delay(1000); // I sometimes need a few seconds to restart the serial console.
  }
  Serial.println();
  if ( Would_I2C_Hang(20, 21) ) { // Adafruit Feather M0 sda and sdl arduino pins.
    Serial.println("The I2C bus will hang if we try to use it. Disabling it.");
  } else {
    Serial.println("Mark the I2C devices as ready to be tested.");
  }
}
void loop() {
  // put your main code here, to run repeatedly:
}

```

# Answer
> 1 votes
Had this same issue when using two Megas communicating over I2C, along with other items running on the I2C bus. I needed the system to continue running if one Mega went down due to loss of power. The other Mega should detect it and execute some abort commands.

Initially I wired the Megas up on the same I2C bus, just as I would any other device. When I unplugged one Mega, the other would freeze the next time it tried to address another device on the bus.

The solution was to use a hot-swappable I2C buffer. I used this one, and everything worked immediately without issue after wiring it up: http://www.mouser.com/search/ProductDetail.aspx?r=595-TCA4311ADR

To integrate the SOIC-8 package onto a standard DIP breadboard for Arduinos, I used an adapter from Adafruit.

# Answer
> 1 votes
Regarding the TI I2C hot swappable buffer:

Apparently there is a similar one from Analog Devices, but I have not tested it: http://www.mouser.com/search/ProductDetail.aspx?r=584-ADUM1250SRZ

To integrate the SOIC-8 package onto a standard DIP breadboard for Arduinos, I used this adapter from Adafruit: https://www.adafruit.com/product/1212

Sorry for another post - limit of 2 hyperlinks per post due to lack of reputation :-)

Chris

---
Tags: arduino-uno, i2c
---


# Question
Title: Lipo Battery level display using nodemcu
I'm designing a connected collar for pets for a project, for this I am using a nodemcu on ESP8266 powered by a Lipo battery I'm guessing around 1000mAh of capacity is enough for a respectable autonomy (? any advices). Lipo model : https://www.lipolbattery.com/lithium%20polymer%20battery.html In order to charge the battery I have found this USB LiPo charger (https://learn.sparkfun.com/tutorials/lipo-usb-charger-hookup-guide/all), my first question is: Is it still usable for higher capacity LiPo batteries (1400mA)? Also I would like to display the battery level via and RGB LED (example: green is for battery FULL battery and RED for LOW battery level in need of charging) is there any way to do this? Thank you

# Answer
> 1 votes
It is still usable for higher capacities. I recommend you tp4056 and some step up converter. You can use resistor divider (that drops safely voltage to nodemcu 3.3v) and connect its output to an analog pin of your nodemcu. Values of resistors must be high, like 10k. You can simply connect your diode to nodemcu and code if voltage is less than 3.2v let the red diode turn on, when above 3.8v let the green diode turn on

# Answer
> 1 votes
Answering the second question "Also I would like to display the battery level...?" (next time, please open a new question for that):

To measure the module voltage level (a.k.a. VCC) of a NodeMCU (which is just a board containing an ESP8266 chip) programmed in Arduino IDE (which I assume given that you ask on the arduino stackexchange), this here applies:

> To read VCC voltage, use ESP.getVcc() and ADC pin must be kept unconnected. Additionally, the following line has to be added to the sketch:
>
> ADC\_MODE(ADC\_VCC);
>
> This line has to appear outside of any functions, for instance right after the #include lines of your sketch.

Source: ESP8266 Arduino reference

So you could just drive a red and a green LED (don't forget the mandatory current limiting resistor) from any other two pins of your NodeMCU. Then switch them in your sketch if VCC falls below 3.2V (you may need to experiment with that because of measurement tolerances; a sketch to start with that would be here.

---
Tags: esp8266, nodemcu, battery, lipo
---


title: Two Arduino Control a LCD Display

text:
# Question
Title: Two Arduino Control a LCD Display
I´m building a system that has two arduinos (like the image on the botton) linked via `ICSP`. The "Programer" programs the second one, called "Worker"( with a .hex file in the SD card of the Programer).

The Worker controls a `LCD 16x4` and displays messages to the user.

What I´m tring to do is when the Programmer is programming the Worker it also displays a message like "Programming, wait" in the Worker LCD. But in code, just telling to the Worker displays a message is not going to happen because when it has been programmed it displays garbage in the LCD.

**Q** So is it possible the the Programmer takes control of the LCD before it begin to program the worker and displays its message?

The LCD works with normal 4-bit mode comunication and I would rather not converte it to I2C if it´s possible.

# Answer
> 2 votes
There are two solutions that come to my mind, one more HW based and another more SW based.

## Solution 1

The HW way is to let the programmer control the LCD through 2:1 multiplexer(s). You will need to connect the LCD pins to the common pin of the multiplexer, the Programmer's ones to one of the two inputs and the Worker's to the other. Then the programmer can choose who controls the LCD through the additional pin. An example of the multiplexer you can choose is the 74LS157, but there are virtually infinite part numbers. The disadvantage of this approach is that you need to write the whole LCD control stack in the Programmer.

## Solution 2

An alternative, more relying on the SW, is implementing a way to let the slave know that you want to program it. For instance, when a programming is needed the Programmer raises a pin; the Worker writes the string on the LCD, then stops working, raises another pin and waits to be cleared. The programmer then proceeds to flash the Worker, and the message will remain on the LCD. It may happen that garbage exits from the Worker's pins when being programmed. If so, change the enable pin or find a way to temporarily detach it from the Worker to avoid signals reaching the LCD. This schematic illustrates this concept:

simulate this circuit – Schematic created using CircuitLab

When the Programmer wants to program the unit, it sets the DL\_Req pin to high. The Worker sees this, and performs accordingly. I think pins are not moved then, but if for instance some noise appears on the signals during programming (and the LCD displays this noise as weird chars), try changing the pin associated to the enable pins (LCD2 in the example above) or put something to prevent noise on that wire only, so that LCD content is not modified.

Personally I'd go with the second solution, but this depends on how much you can change the behavior of the worker and programmer

---
Tags: arduino-uno, programming, lcd
---


# Question
Title: Soil moisture sensor not working in "pcb"
I have a little and common application in which a sc-28 moisture sensor reads humidity levels and turns a servo (which drives a little faucet) if the soil needs water. Arduino nano is the brain.

All of them is tested and working fine on the proto board. Soil sensor is powered by 5v rail of arduino and everything seems fine even with the servo pulling from 5v rail too.

With all working, I try to translate that to a perfboard. The only difference in circuits are how they are powered.

While the prototype is powered via usb, the definitive one is powered through a 24v psu, leveling the voltage with a lm2596 module down to 5v.

Then this 5v feeds the nano (vin pin) and servo, while the soil sensor still pulls from 5v rail of the arduino to avoid vref problems.

And then, the sensor does not work. No led indicating power or data. This were my steps trying to debug it:

* **Triple check every connection on the board.** While I am a decent programmer, my solder skills are kind of lacking. But everything looks fine, nothing shorted or loose.
* **measure voltage**. On the perfboard, voltage between vcc and gnd connector pins spits 4.78v, which is supposed to be in range for the sensor to work.
* **Power the board through usb** I tried this too, and is not working. Lm module and arduino lights up, code can be executed. I can't explain why the lm2596 module lights up too, and I'm thinking is part of the problem but I do not know. Voltage at soil sensor is still 4.78

And then I'm done. I dont know what could be happening and I only can make wild guesses. It's obviously a board problem, and i am aware I am doing something wrong but I can't see it.

Below, my horror soldering skills and the board. Soil sensor is the 4pin females at the bottom left and servo the 3pin males at the bottom right.

# Answer
The answer was, in fact, my poor experience with these boards and how they work.

As you can see in the pictures, wire and connectors are on opposite sides of the board. I was assuming that pads were connected on both sides, which is not true. Therefore, connectors were simply dead.

Soldered again at the wire side and it works like a charm. Thank you all for every suggestion, and the learning experience.
> 1 votes

# Answer
> Then this 5v feeds the nano (vin pin)

Can't feed 5V into Vin and get 5V out. Connect 5V to the 5V pin.
> 0 votes

---
Tags: sensors, arduino-nano, breadboard
---


title: No data from U-Blox Neo-6M

text:
# Question
Title: No data from U-Blox Neo-6M
I'm trying to get Neo-6M module to work with Arduino Uno, but it just isn't transmitting any data. It is getting 3.3V.
I've tried measuring the Amps and I got zero, so I'm afraid that the module could be broken.

Neo-6M wiring:
Arduino wiring (power):
Arduino wiring (data):

Arduino code:

```
#include <TinyGPS++.h>
#include <SoftwareSerial.h>
/*
   This sample sketch demonstrates the normal use of a TinyGPS++ (TinyGPSPlus) object.
   It requires the use of SoftwareSerial, and assumes that you have a
   4800-baud serial GPS device hooked up on pins 4(rx) and 3(tx).
*/
static const int RXPin = 4, TXPin = 3;
static const uint32_t GPSBaud = 9600;

// The TinyGPS++ object
TinyGPSPlus gps;

// The serial connection to the GPS device
SoftwareSerial ss(RXPin, TXPin);

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

  Serial.println(F("DeviceExample.ino"));
  Serial.println(F("A simple demonstration of TinyGPS++ with an attached GPS module"));
  Serial.print(F("Testing TinyGPS++ library v. "));     Serial.println(TinyGPSPlus::libraryVersion());
  Serial.println(F("by Mikal Hart"));
  Serial.println();
}

void loop()
{
  // This sketch displays information every time a new sentence is correctly encoded.
  while (ss.available() > 0)
    if (gps.encode(ss.read()))
      displayInfo();

  if (millis() > 5000 && gps.charsProcessed() < 10)
  {
    Serial.println(F("No GPS detected: check wiring."));
    while(true);
  }
}

void displayInfo()
{
  Serial.print(F("Location: "));
  if (gps.location.isValid())
  {
    Serial.print(gps.location.lat(), 6);
    Serial.print(F(","));
    Serial.print(gps.location.lng(), 6);
  }
  else
  {
    Serial.print(F("INVALID"));
  }

  Serial.print(F("  Date/Time: "));
  if (gps.date.isValid())
  {
    Serial.print(gps.date.month());
    Serial.print(F("/"));
    Serial.print(gps.date.day());
    Serial.print(F("/"));
    Serial.print(gps.date.year());
  }
  else
  {
    Serial.print(F("INVALID"));
  }

  Serial.print(F(" "));
  if (gps.time.isValid())
  {
    if (gps.time.hour() < 10) Serial.print(F("0"));
    Serial.print(gps.time.hour());
    Serial.print(F(":"));
    if (gps.time.minute() < 10) Serial.print(F("0"));
    Serial.print(gps.time.minute());
    Serial.print(F(":"));
    if (gps.time.second() < 10) Serial.print(F("0"));
    Serial.print(gps.time.second());
    Serial.print(F("."));
    if (gps.time.centisecond() < 10) Serial.print(F("0"));
    Serial.print(gps.time.centisecond());
  }
  else
  {
    Serial.print(F("INVALID"));
  }

  Serial.println();
}

```

# Answer
> 1 votes
I run my board from the 5v Arduino tap as it has a 3.3v low drop off voltage regulator on board. So my belief is that you should also tap off the Arduino boards 5v supply.

Mine draws about 60ma from the Arduino board. The device should get a fix, then start transmitting over the tx line. Indicated by the 'Position Fixed' led indicator on board, flashing once a second (at 9600 baud.)

Good luck, keep in mind that these boards are only about $7.50 on Amazon, order a couple for peace of mind. :)

# Answer
> 1 votes
It isn't enough to power the module with 3.3V. You also have to level-shift the Arduino's 5V TX signal to 3.3V that is acceptable by the GPS module's RX pin, using a 1:2 voltage divider.

You should also know that the Arduino's 3.3 V pin can't source more than 50 mA; your module's current draw may sometimes exceed this limit (max is 67 mA). Instead, connect the Arduino's 5 V pin (which can source up to 500 mA) to the VCC of the GPS module through an LM1117T 3.3 V regulator:

The input goes the Arduino 5V pin and the output goes to the NEO-6M VCC. Connect all GNDs together.

Then run a basic sketch like this:

```
#include "SoftwareSerial.h"

SoftwareSerial gps(4,3);

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

void loop(){
  while (gps.available())
    Serial.write(gps.read());
}

```

This will basically make the Arduino grab any NMEA data sent by the NEO-6M and forward it to your PC's serial monitor. If you receive legible data, it means you've established comms with the module. You can then upload your original sketch.

---
Tags: gps
---


# Question
Title: What Arduino boards would be compatible?
I am considering using an arduino over the raspberry pi for a new project. However, I am not sure what arduino I should buy so that it is compatible with the below add-on.

Are all Arduinos compatible?

TIA.

Edit:

Link to product- https://www.adafruit.com/product/3387

My goal is to use an arduino with the above product to move a 3D model in Unity 3D.

# Answer
As one can see from the pinout description page (https://learn.adafruit.com/adafruit-lsm9ds1-accelerometer-plus-gyro-plus-magnetometer-9-dof-breakout/pinouts):

So this board is literally designed to be powered by 3.3V and 5V and have compatible logic levels for both these voltage ranges, which is what every Arduino known to me and the Raspberry Pi use.

Furthermore, there is also Arduino Code (https://github.com/adafruit/Adafruit\_LSM9DS1) which is compatible with pretty much every Arduino Core and Raspberry Pi Python code (https://learn.adafruit.com/adafruit-lsm9ds1-accelerometer-plus-gyro-plus-magnetometer-9-dof-breakout/python-circuitpython).

So by means of voltage levels and platforms, this board is highly compatible with everything out there that is either 3.3V or 5V powered and has a SPI or I2C peripheral.
> 3 votes

---
Tags: arduino-uno
---


# Question
Title: How do I make the letters on my Arduino LED matrix scroll faster?
```
////*************************************************************************
////----------------1.开发环境:Arduino IDE or Visual Studio 2010----------------
////----------------2.使用开发板型号：Arduino UNO          ----------------
////----------------3.单片机使用晶振：16M                   ----------------
////----------------4.店铺名称：大学生电子商铺/小强电子设计  ----------------
////----------------5.淘宝网址：Ilovemcu.taobao.com       ----------------
////----------------        52dpj.taobao.com                ----------------
////----------------6.作者：神秘藏宝室              ----------------
////***********************************************************************

#include <Arduino.h>

//IO配置
#define LEDARRAY_D 5
#define LEDARRAY_C 6
#define LEDARRAY_B 7
#define LEDARRAY_A 8
#define LEDARRAY_G 9
#define LEDARRAY_DI 10
#define LEDARRAY_CLK 11
#define LEDARRAY_LAT 12

#define led 13

#define Display_Num_Word 2              //液晶能显示的汉字个数

unsigned char Display_Buffer[8];
unsigned char Display_Swap_Buffer[Display_Num_Word][32]={0};                    //显示缓冲区
bool Shift_Bit = 0;
bool Flag_Shift = 0;
unsigned char Timer0_Count = 0;
unsigned char temp = 0x80;
unsigned char Shift_Count = 0;
unsigned char Display_Word_Count = 0;

#define Num_Of_Word 33
const unsigned char Word[Num_Of_Word][32] =
{
0xFF,0xFF,0xFF,0x07,0xBB,0xBB,0xBB,0x87,0xBB,0xBD,0xBD,0xBD,0xBB,0x07,0xFF,0xFF,/*"B",0*/
0xFF,0xFF,0xFF,0xC7,0xBB,0x7D,0x7D,0x7D,0x7D,0x7D,0x7D,0x7D,0xBB,0xC7,0xFF,0xFF,/*"O"*/
0xFF,0xFF,0xFF,0x83,0xEF,0xEF,0xEF,0xEF,0xEF,0xEF,0xEF,0xEF,0xEF,0x83,0xFF,0xFF,/*"I",0*/
0xFF,0xFF,0xFF,0x1F,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0x01,0xFF,0xFF,
0xFF,0xFF,0xFF,0xC1,0xBD,0xBD,0xBF,0xDF,0xE7,0xFB,0xFD,0xBD,0xBD,0x83,0xFF,0xFF,/*"S"*/
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,/*" Space",0*/
0xFF,0xFF,0xFF,0xEF,0xEF,0xE7,0xD7,0xD7,0xDB,0xC3,0xBB,0xBD,0xBD,0x18,0xFF,0xFF,/*"A",0*/
0xFF,0xFF,0xFF,0x03,0xBD,0xBD,0xBD,0x83,0xB7,0xB7,0xBB,0xBB,0xBD,0x1C,0xFF,0xFF,/*"R",0*/
0xFF,0xFF,0xFF,0x81,0xBF,0xBF,0xBF,0x83,0xBF,0xBF,0xBF,0xBF,0xBF,0x81,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,/*" Space",0*/
0xFF,0xFF,0xFF,0xEF,0xEF,0xE7,0xD7,0xD7,0xDB,0xC3,0xBB,0xBD,0xBD,0x18,0xFF,0xFF,/*"A",0*/
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,/*" Space",0*/
0xFF,0xFF,0xFF,0x83,0xBD,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBD,0x83,0xFF,0xFF,
0xFF,0xFF,0xFF,0x1F,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0x01,0xFF,0xFF,
0xFF,0xFF,0xFF,0x81,0xBF,0xBF,0xBF,0x83,0xBF,0xBF,0xBF,0xBF,0xBF,0x81,0xFF,0xFF,
0xFF,0xFF,0xFF,0xEF,0xEF,0xE7,0xD7,0xD7,0xDB,0xC3,0xBB,0xBD,0xBD,0x18,0xFF,0xFF,/*"A",0*/
0xFF,0xFF,0xFF,0x03,0xBD,0xBD,0xBD,0x83,0xB7,0xB7,0xBB,0xBB,0xBD,0x1C,0xFF,0xFF,/*"R",0*/
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,/*" Space",0*/
0xFF,0xFF,0xFF,0xC1,0xBD,0xBD,0xBF,0xDF,0xE7,0xFB,0xFD,0xBD,0xBD,0x83,0xFF,0xFF,/*"S"*/
0xFF,0xFF,0xFF,0x83,0xEF,0xEF,0xEF,0xEF,0xEF,0xEF,0xEF,0xEF,0xEF,0x83,0xFF,0xFF,/*"I",0*/
0xFF,0xFF,0xFF,0xC3,0xBB,0xBB,0x7F,0x7F,0x7F,0x71,0x7B,0xBB,0xBB,0xC7,0xFF,0xFF,/*"G",0*/
0xFF,0xFF,0xFF,0xBF,0x83,0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,/*" Space",0*/
0xFF,0xFF,0xFF,0xC7,0xBB,0x7D,0x7D,0x7D,0x7D,0x7D,0x7D,0x7D,0xBB,0xC7,0xFF,0xFF,/*"O"*/
0xFF,0xFF,0xFF,0x81,0xBF,0xBF,0xBF,0x83,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,/*" Space",0*/
0xFF,0xFF,0xFF,0x01,0x6D,0xEF,0xEF,0xEF,0xEF,0xEF,0xEF,0xEF,0xEF,0xC7,0xFF,0xFF,/*"T",0*/
0xFF,0xFF,0xFF,0x18,0xBD,0xBD,0xBD,0xBD,0x81,0xBD,0xBD,0xBD,0xBD,0x18,0xFF,0xFF,/*"H",0*/
0xFF,0xFF,0xFF,0x81,0xBF,0xBF,0xBF,0x83,0xBF,0xBF,0xBF,0xBF,0xBF,0x81,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,/*" Space",0*/
0xFF,0xFF,0xFF,0x07,0xBB,0xBB,0xBB,0x87,0xBB,0xBD,0xBD,0xBD,0xBB,0x07,0xFF,0xFF,/*"B",0*/
0xFF,0xFF,0xFF,0x1F,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0x01,0xFF,0xFF,
0xFF,0xFF,0xFF,0xEF,0xEF,0xE7,0xD7,0xD7,0xDB,0xC3,0xBB,0xBD,0xBD,0x18,0xFF,0xFF,/*"A",0*/
0xFF,0xFF,0xFF,0x83,0xBD,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBD,0x83,0xFF,0xFF,
0xFF,0xFF,0xFF,0xBE,0xBD,0xBB,0xB7,0xB7,0xBB,0xBB,0xBD,0xBD,0xBE,0xBE,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,/*" Space",0*/
0xFF,0xFF,0xFF,0x07,0xBB,0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,0xBB,0x07,0xFF,0xFF,/*"D",0*/
0xFF,0xFF,0xFF,0x81,0xBF,0xBF,0xBF,0x83,0xBF,0xBF,0xBF,0xBF,0xBF,0x81,0xFF,0xFF,
0xFF,0xFF,0xFF,0xEF,0xEF,0xE7,0xD7,0xD7,0xDB,0xC3,0xBB,0xBD,0xBD,0x18,0xFF,0xFF,/*"A",0*/
0xFF,0xFF,0xFF,0x01,0x6D,0xEF,0xEF,0xEF,0xEF,0xEF,0xEF,0xEF,0xEF,0xC7,0xFF,0xFF,/*"T",0*/
0xFF,0xFF,0xFF,0x18,0xBD,0xBD,0xBD,0xBD,0x81,0xBD,0xBD,0xBD,0xBD,0x18,0xFF,0xFF,/*"H",0*/
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,/*" Space",0*/
0xFF,0xFF,0xFF,0xDF,0xD7,0xB7,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xBE,0xBD,0xBB,0xB7,0xB7,0xBB,0xBB,0xBD,0xBD,0xBE,0xBE,0xFF,0xFF,
0xFF,0xFF,0xFF,0x83,0xBD,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBD,0x83,0xFF,0xFF,
0xFF,0xFF,0xFF,0x81,0xBF,0xBF,0xBF,0x83,0xBF,0xBF,0xBF,0xBF,0xBF,0x81,0xFF,0xFF,
0xFF,0xFF,0xFF,0x81,0xBF,0xBF,0xBF,0x83,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xFF,0xFF,
0xFF,0xFF,0xFF,0x1F,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0x01,0xFF,0xFF,
};
void setup()
{
    pinMode(LEDARRAY_D, OUTPUT);
    pinMode(LEDARRAY_C, OUTPUT);
    pinMode(LEDARRAY_B, OUTPUT);
    pinMode(LEDARRAY_A, OUTPUT);
    pinMode(LEDARRAY_G, OUTPUT);
    pinMode(LEDARRAY_DI, OUTPUT);
    pinMode(LEDARRAY_CLK, OUTPUT);
    pinMode(LEDARRAY_LAT, OUTPUT);

    Clear_Display();
}

void loop()
{
    unsigned int i;
    for(i = 0;i<30;i++)
    {
        Display(Display_Swap_Buffer);
    }
    Display_Word_Count = Shift_Count/16;                //计算当前显示第几个字
    Calc_Shift();

    Shift_Count++;

    if(Shift_Count == (Num_Of_Word+Display_Num_Word)*16 )               //移动次数
    {
        Shift_Count = 0;
    }
}

//************************************************************
//清空缓冲区
//************************************************************
void Clear_Display()
{
    unsigned char i,j;
    for(j = 0 ; j < Display_Num_Word; j++)
    {
        for(i = 0 ; i < 32 ;i++)
        {
            Display_Swap_Buffer[j][i] = 0xff;               //0=显示  1=不显示
        }
    }
}

//************************************************************
//计算移动数据，存在在缓冲器
//************************************************************
void Calc_Shift()
{
    unsigned char i;

    for(i = 0;i < 16;i++)
    {
        if((Display_Swap_Buffer[0][16+i]&0x80) == 0)                                    //每行第一个字节移位
        {
            Display_Swap_Buffer[0][i] = (Display_Swap_Buffer[0][i] << 1)&0xfe;          //最低位清零
        }
        else
        {
            Display_Swap_Buffer[0][i] = (Display_Swap_Buffer[0][i] << 1)|0x01;          //最低位置一
        }

        if((Display_Swap_Buffer[1][i]&0x80) == 0)                                   //每行第二个字节移位
        {
            Display_Swap_Buffer[0][16+i] = (Display_Swap_Buffer[0][16+i] << 1)&0xfe;            //最低位清零
        }
        else
        {
            Display_Swap_Buffer[0][16+i] = (Display_Swap_Buffer[0][16+i] << 1)|0x01;            //最低位置一
        }

        if((Display_Swap_Buffer[1][16+i]&0x80) == 0)                                    //每行第三个字节移位
        {
            Display_Swap_Buffer[1][i] = (Display_Swap_Buffer[1][i] << 1)&0xfe;          //最低位清零
        }
        else
        {
            Display_Swap_Buffer[1][i] = (Display_Swap_Buffer[1][i] << 1)|0x01;          //最低位置一
        }

        if(Shift_Count%16 < 8 && Display_Word_Count < Num_Of_Word)
        {
            Shift_Bit = Word[Display_Word_Count][i]&temp;
        }
        else if(Shift_Count%16 < 16 && Display_Word_Count < Num_Of_Word)
        {
            Shift_Bit = Word[Display_Word_Count][16+i]&temp;
        }
        else
        {
            Shift_Bit = 1;                      //把字移出缓冲区
        }

        if( Shift_Bit == 0)                                                     //后8位移位
        {
            Display_Swap_Buffer[1][16+i] = (Display_Swap_Buffer[1][16+i] << 1)&0xfe;        //最低位清零
        }
        else
        {
            Shift_Bit = 1;
            Display_Swap_Buffer[1][16+i] = (Display_Swap_Buffer[1][16+i] << 1)|0x01;        //最低位置一
        }

    }
    temp = (temp>>1)&0x7f;
    if(temp == 0x00)
    {
        temp = 0x80;
    }
}
//************************************************************
//num为字数  dat[][32]为字模的名称
//*************************************************************
void Display(const unsigned char dat[][32])
{
    unsigned char i;

    for( i = 0 ; i < 16 ; i++ )
    {
        digitalWrite(LEDARRAY_G, HIGH);     //更新数据时候关闭显示。等更新完数据，打开138显示行。防止重影。

        Display_Buffer[0] = dat[0][i];
        Display_Buffer[1] = dat[0][i+16];
        Display_Buffer[2] = dat[1][i];
        Display_Buffer[3] = dat[1][i+16];

    Display_Buffer[4] = dat[2][i];
    Display_Buffer[5] = dat[2][i+16];
    Display_Buffer[6] = dat[3][i];
    Display_Buffer[7] = dat[3][i+16];

    Send(Display_Buffer[7]);
    Send(Display_Buffer[6]);
    Send(Display_Buffer[5]);
    Send(Display_Buffer[4]);

        Send(Display_Buffer[3]);
        Send(Display_Buffer[2]);
        Send(Display_Buffer[1]);
        Send(Display_Buffer[0]);

        digitalWrite(LEDARRAY_LAT, HIGH);                   //锁存数据
        delayMicroseconds(0.1);

        digitalWrite(LEDARRAY_LAT, LOW);
        delayMicroseconds(0.1);

        Scan_Line(i);                       //选择第i行

        digitalWrite(LEDARRAY_G, LOW);

        delayMicroseconds(100);;        //延时一段时间，让LED亮起来。
    }
}

//****************************************************
//扫描某一行
//****************************************************
void Scan_Line( unsigned char m)
{
    switch(m)
    {
        case 0:
            digitalWrite(LEDARRAY_D, LOW);digitalWrite(LEDARRAY_C, LOW);digitalWrite(LEDARRAY_B, LOW);digitalWrite(LEDARRAY_A, LOW);
            break;
        case 1:
            digitalWrite(LEDARRAY_D, LOW);digitalWrite(LEDARRAY_C, LOW);digitalWrite(LEDARRAY_B, LOW);digitalWrite(LEDARRAY_A, HIGH);
            break;
        case 2:
            digitalWrite(LEDARRAY_D, LOW);digitalWrite(LEDARRAY_C, LOW);digitalWrite(LEDARRAY_B, HIGH);digitalWrite(LEDARRAY_A, LOW);
            break;
        case 3:
            digitalWrite(LEDARRAY_D, LOW);digitalWrite(LEDARRAY_C, LOW);digitalWrite(LEDARRAY_B, HIGH);digitalWrite(LEDARRAY_A, HIGH);
            break;
        case 4:
            digitalWrite(LEDARRAY_D, LOW);digitalWrite(LEDARRAY_C, HIGH);digitalWrite(LEDARRAY_B, LOW);digitalWrite(LEDARRAY_A, LOW);
            break;
        case 5:
            digitalWrite(LEDARRAY_D, LOW);digitalWrite(LEDARRAY_C, HIGH);digitalWrite(LEDARRAY_B, LOW);digitalWrite(LEDARRAY_A, HIGH);
            break;
        case 6:
            digitalWrite(LEDARRAY_D, LOW);digitalWrite(LEDARRAY_C, HIGH);digitalWrite(LEDARRAY_B, HIGH);digitalWrite(LEDARRAY_A, LOW);
            break;
        case 7:
            digitalWrite(LEDARRAY_D, LOW);digitalWrite(LEDARRAY_C, HIGH);digitalWrite(LEDARRAY_B, HIGH);digitalWrite(LEDARRAY_A, HIGH);
            break;
        case 8:
            digitalWrite(LEDARRAY_D, HIGH);digitalWrite(LEDARRAY_C, LOW);digitalWrite(LEDARRAY_B, LOW);digitalWrite(LEDARRAY_A, LOW);
            break;
        case 9:
            digitalWrite(LEDARRAY_D, HIGH);digitalWrite(LEDARRAY_C, LOW);digitalWrite(LEDARRAY_B, LOW);digitalWrite(LEDARRAY_A, HIGH);
            break;
        case 10:
            digitalWrite(LEDARRAY_D, HIGH);digitalWrite(LEDARRAY_C, LOW);digitalWrite(LEDARRAY_B, HIGH);digitalWrite(LEDARRAY_A, LOW);
            break;
        case 11:
            digitalWrite(LEDARRAY_D, HIGH);digitalWrite(LEDARRAY_C, LOW);digitalWrite(LEDARRAY_B, HIGH);digitalWrite(LEDARRAY_A, HIGH);
            break;
        case 12:
            digitalWrite(LEDARRAY_D, HIGH);digitalWrite(LEDARRAY_C, HIGH);digitalWrite(LEDARRAY_B, LOW);digitalWrite(LEDARRAY_A, LOW);
            break;
        case 13:
            digitalWrite(LEDARRAY_D, HIGH);digitalWrite(LEDARRAY_C, HIGH);digitalWrite(LEDARRAY_B, LOW);digitalWrite(LEDARRAY_A, HIGH);
            break;
        case 14:
            digitalWrite(LEDARRAY_D, HIGH);digitalWrite(LEDARRAY_C, HIGH);digitalWrite(LEDARRAY_B, HIGH);digitalWrite(LEDARRAY_A, LOW);
            break;
        case 15:
            digitalWrite(LEDARRAY_D, HIGH);digitalWrite(LEDARRAY_C, HIGH);digitalWrite(LEDARRAY_B, HIGH);digitalWrite(LEDARRAY_A, HIGH);
            break;
        default : break;
    }
}

//****************************************************
//发送数据
//****************************************************
void Send( unsigned char dat)
{
    unsigned char i;
    digitalWrite(LEDARRAY_CLK, LOW);
    delayMicroseconds(0);;
    digitalWrite(LEDARRAY_LAT, LOW);
    delayMicroseconds(0);;

    for( i = 0 ; i < 8 ; i++ )
    {
        if( dat&0x01 )
        {
            digitalWrite(LEDARRAY_DI, HIGH);
        }
        else
        {
            digitalWrite(LEDARRAY_DI, LOW);
        }

        digitalWrite(LEDARRAY_CLK, HIGH);               //上升沿发送数据
            delayMicroseconds(0);;
        digitalWrite(LEDARRAY_CLK, LOW);
            delayMicroseconds(0);;
        dat >>= 1;

    }
}

```

# Answer
You have 30x loop calling Display() that inside a 16X loop calls eight Send() that inside an 8x loop makes three digital writes each taking at least 2us to complete. At a minimum, only digitalWrite takes 180ms in one pass.

Use SPI if possible or search Google for "arduino speed up digitalWrite" , here is a good article on this.

Also unrolling the 8x loop inside Send() like this can spare some ms:

```
   if( dat&0x01 ) digitalWrite(LEDARRAY_DI, HIGH);
   else digitalWrite(LEDARRAY_DI, LOW);
   digitalWrite(LEDARRAY_CLK, HIGH);               //上升沿发送数据
   delayMicroseconds(0);;
   digitalWrite(LEDARRAY_CLK, LOW);
   delayMicroseconds(0);
   if( dat&0x02 ) digitalWrite(LEDARRAY_DI, HIGH);
   else digitalWrite(LEDARRAY_DI, LOW);
   digitalWrite(LEDARRAY_CLK, HIGH);               //上升沿发送数据
   delayMicroseconds(0);;
   digitalWrite(LEDARRAY_CLK, LOW);
   delayMicroseconds(0);
   ........
   if( dat&0x80 ) digitalWrite(LEDARRAY_DI, HIGH);
   else digitalWrite(LEDARRAY_DI, LOW);
   digitalWrite(LEDARRAY_CLK, HIGH);               //上升沿发送数据
   delayMicroseconds(0);;
   digitalWrite(LEDARRAY_CLK, LOW);
   delayMicroseconds(0);

```
> 1 votes

# Answer
These lines

```
    digitalWrite(LEDARRAY_LAT, HIGH);                   //锁存数据
    delayMicroseconds(0.1);

    digitalWrite(LEDARRAY_LAT, LOW);
    delayMicroseconds(0.1);

    Scan_Line(i);                       //选择第i行

    digitalWrite(LEDARRAY_G, LOW);

    delayMicroseconds(100);;        //延时一段时间，让LED亮起来。

```

Reduce the time in the last one. I don't think delayMicroseconds(0.1); does anything, nor does delayMicroseconds(0); found elsewhere.

I see individual pins being controlled

```
#define LEDARRAY_D 5
#define LEDARRAY_C 6
#define LEDARRAY_B 7
#define LEDARRAY_A 8
#define LEDARRAY_G 9
#define LEDARRAY_DI 10
#define LEDARRAY_CLK 11
#define LEDARRAY_LAT 12

```

You don't say what the hardware is, but I bet you replace writing individual pins with blasting data out serially to a shift register with 8 MHz SPI clock as a way speed things up. Or if you had a '1284P or '2560 board, then you could do port writes also.
> 0 votes

---
Tags: arduino-uno, led
---


title: RN4678 Bluetooth doesn't respond

text:
# Question
Title: RN4678 Bluetooth doesn't respond
I am facing very basic level issue with RN4678. I purchased a module from https://www.mikroe.com/rn4678-click

I want to simply communicate with it through serial port. To do that I connected it to PC by usb to TTL. Whatever I send, I don't get any response from module. Then parallely I paired it with mobile phone and on successful connection, from Android app terminal I tried the same and nothing happened. If I send something from PC, I get it on mobile but reverse doesn't work. And the main issue is Module doesn't respond at all. I tried 3modules as well.
Help would be appreciated.

# Answer
> 0 votes
Have you made sure that your USB to TTL is implementing flow control on the UART. An option is to delete the CTS/RST in RN configuration and try two wire UART to eliminate CTS/RTS option

---
Tags: bluetooth
---


# Question
Title: Protocol options for data exchange between Arduino and ESP8266
I have a device built with an Arduino uno:

* Arduino software installed on an Arduino uno
* can be controlled via serial commands
* can be controlled via physical buttons and sensors
* on any button/sensor state change it writes the current state to serial
* if no message has been sent within 5 seconds, it sends a no-change serial message

---

What is needed:

* Use an ESP8266 to provide a bridge between current Arduino software and MQTT / web
* I can program the ESP8266 as a web server, MQTT client, etc with the Arduino IDE or Lua (but I prefer the Arduino IDE since I can reuse parts of the code to generate / interpret communication).
* the ESP8266 will handle everything that is required for wifi / web / MQTT; without the MQTT module the Arduino part will work stand-alone, only the remote control will be missing.
* I would like to make minimal changes to the Arduino code (or none, if possible). Any changes would involve extensive re-testing, which I try to avoid.
* the ESP8266 can be missing in some installs.

---

What options I found:

1. Serial

ESP8266 can read the serial output and be a bridge between web/MQTT and serial, will store the current state in memory to be sent when requested to avoid polling the device every time.

One of the benefits is no code changes / testing required for the Arduino part.

2. I2C

Make the Arduino the I2C master and the ESP8266 the slave (or the other way around) and implement bi-directional communication. Got the idea by reading this thread.

---

Some other information about the serial commands:

A data packet (command or state description) consists of 1 to 20 characters, with a possible peak of 20 packets in 5 seconds, and an average of one packet every 3 seconds. If needed, I can make this send 5 unsigned integers instead of alphanumeric characters.

If more than the I2C / serial pins are needed I can upgrade to an Arduino Mega (so the number of free pins is not an issue).

Are there any other options for this? (protocols, pre-made libraries for serial communication, etc). I'm trying not to reinvent the wheel..

Thank you for your time!

# Answer
> 4 votes
Most I2C tutorials made each Arduino a slave and master, but this approach is better, because each Arduino is either a master or a slave (not both) and no switching is needed. That makes things easier.

I2C is better than serial, because you can add more Arduinos in the same bus.

I have implemented I2C between two Arduinos and it's not more complicated that reading/writing to the serial port (which you have already done). And I bet you can generalize your serial port code to work with both serial and I2C comms.

This is my example (just a proof of concept). The slave Arduino controls a some pins, a temp. sensor and a watchdog under orders from the master Arduino. If slave doesn't receive a beat in time, it reset the master Arduino.

**Master code**

```
#include <Wire.h>

#define CMD_SENSOR    1
#define CMD_PIN_ON    2
#define CMD_PIN_OFF   3
#define CMD_LUMEN     4
#define CMD_BEAT      5

const byte SLAVE_ADDRESS = 42;
const byte LED = 13;

char buffer[32];

void setup ()
{
  Serial.begin(9600);
  Serial.println("Master");

  Wire.begin ();

  pinMode (LED, OUTPUT);
  digitalWrite(LED, HIGH);
  delay(1000);
  digitalWrite(LED, LOW);

  Wire.beginTransmission (SLAVE_ADDRESS);
  Serial.println("Send LED on");
  Wire.write (CMD_PIN_ON);
  Wire.write (2);
  Wire.write (10);
  Wire.endTransmission();
  int x = Wire.requestFrom(SLAVE_ADDRESS, 1);
  Serial.print("status=");
  Serial.println(x);
}  // end of setup

void loop ()
{
  Serial.println(".");
  Wire.beginTransmission (SLAVE_ADDRESS);
  Wire.write (CMD_SENSOR);
  Wire.endTransmission();
  int x = Wire.requestFrom(SLAVE_ADDRESS, 1);
  Serial.print("Disponibles = ");
  Serial.println(x);
  int temp = (int) Wire.read();
  Serial.println(temp);

  Wire.beginTransmission (SLAVE_ADDRESS);
  Wire.write (CMD_LUMEN);
  Wire.endTransmission();
  Wire.requestFrom(SLAVE_ADDRESS, 2);
  int light = Wire.read() << 8 | Wire.read();
  Serial.print("Light=");
  Serial.println(light);

  Wire.beginTransmission (SLAVE_ADDRESS);
  Wire.write (CMD_BEAT);
  Wire.endTransmission();
  Wire.requestFrom(SLAVE_ADDRESS, 1);

  delay (5000);
}  // end of loop

```

**Slave code**

```
/*
   Esclavo I2C

   Recibe los siguientes comandos
   <- 1° byte -> <- 2° byte -> <- 3° byte ->
   CMD_SENSOR
   CMD_PIN_ON    n° de pin     duracion en segundos
   CMD_PIN_OFF   n° de pin
   CMD_LUMEN
   CMD_BEAT

   Cada comando recibe una respuesta, ya sea el valor pedido
   o un status.
*/
#include <max6675.h>
#include <Wire.h>

typedef struct {
  int pin;
  unsigned long off;
} PIN_PGMA;

/*
   Lista de pines que se pueden activar via CMD_PIN_ON.
*/
#define PIN_LUMEN   A0
#define PIN_LED      2
#define PIN_RESET    3
PIN_PGMA pgma[] = {
  {PIN_LED, 0},
  {PIN_RESET, 0}
};
const int pgmaSize = sizeof(pgma) / sizeof(PIN_PGMA);

#define CMD_SENSOR    1
#define CMD_PIN_ON    2
#define CMD_PIN_OFF   3
#define CMD_LUMEN     4
#define CMD_BEAT      5

#define ST_OK         0
#define ST_BAD_PIN    1
#define ST_TIME_0     2
#define ST_BAD_LEN    3

#define MY_ADDRESS  42

//  Maximo tiempo de espera entre comandos CMD_BEAT. Pasado
//  ese tiempo, se activa el PIN_RESET.
//  En milisegundos.
#define BEAT_INTERVAL 10000
unsigned long lastBeat;
//  Largo del reset en milisegundos.
#define RESET_LENGTH  250
byte cmd = 0;
byte status = 0;

int thermoDO = 11;
int thermoCS = 12;
int thermoCLK = 13;

MAX6675 thermocouple(thermoCLK, thermoCS, thermoDO);

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

  pinMode(PIN_LUMEN, INPUT);
  analogRead(PIN_LUMEN);

  for (int i = 0; i < pgmaSize; i++) {
    pinMode(pgma[i].pin, OUTPUT);
    digitalWrite(pgma[i].pin, LOW);
  }
  lastBeat = millis();

  Wire.begin (MY_ADDRESS);
  Wire.onReceive (receiveCommand);
  Wire.onRequest (sendAnswer);
}

void loop()
{
  unsigned long now = millis();

  //  Baja la linea de RESET si no ha recibido un beat ultimamente.
  unsigned long diff = now - lastBeat;
  if (diff > BEAT_INTERVAL) {
    resetPin();
  }

  //  Recorre la lista de pines y apaga aquellos cuyo tiempo termino.
  for (int i = 0; i < pgmaSize; i++) {
    if (pgma[i].off > 0 && pgma[i].off <= now) {
      Serial.print("off pin="); Serial.println(pgma[i].pin);
      pgma[i].off = 0;
      digitalWrite(pgma[i].pin, LOW);
    }
  }
}

// called by interrupt service routine when outgoing data is requested
void sendAnswer() {
  byte temp;
  int  lightReading;

  switch (cmd) {
    case CMD_SENSOR:
      temp = thermocouple.readCelsius();
      Wire.write(temp);
      break;
    case CMD_LUMEN:
      lightReading  = analogRead(PIN_LUMEN);
      Wire.write(lightReading >> 8);
      Wire.write(lightReading % 0xFF);
      break;
    case CMD_PIN_ON:
    case CMD_PIN_OFF:
    case CMD_BEAT:
      Wire.write(status);
      status = ST_OK;
      break;
  }
  cmd = 0;
}

// called by interrupt service routine when incoming data arrives
void receiveCommand (int howMany) {
  cmd = Wire.read ();
  status = ST_OK;
  switch (cmd) {
    case CMD_PIN_ON:
      cmdPinOn();;
      break;
    case CMD_PIN_OFF:
      cmdPinOff();
      break;
    case CMD_BEAT:
      lastBeat = millis();
      break;
  }
}  // end of receiveEvent

void cmdPinOff() {
  if (Wire.available() != 1) {
    status = ST_BAD_LEN;
  } else {
    int pin = Wire.read();
    int i = searchPin(pin);
    if (i < 0) {
      status = ST_BAD_PIN;
    }
    else {
      pgma[i].off = 0;
      digitalWrite(pin, LOW);
    }
  }
}

int searchPin(int pin) {
  int i = pgmaSize - 1;
  while (i >= 0 && pgma[i].pin != pin) {
    i--;
  }
  return i;
}

/*
 * Programa el encendido y duracion del RESET.
 */
void resetPin() {
  if (digitalRead(PIN_RESET) == LOW) {
    unsigned long now = millis();

    int i = searchPin(PIN_RESET);

    pgma[i].off = now + RESET_LENGTH;
    lastBeat = now;
    digitalWrite(PIN_RESET, HIGH);
  }
}

void cmdPinOn() {
  if (Wire.available() != 2) {
    status = ST_BAD_LEN;
  } else {
    int pin = Wire.read();
    int len = Wire.read();

    int i = searchPin(pin);
    Serial.print("pin="); Serial.print(pin); Serial.print(",index="); Serial.println(i);
    if (i < 0) {
      status = ST_BAD_PIN;
      Serial.println("bad pin");
    } else {
      if (len == 0) {
        status = ST_TIME_0;
        Serial.println("ban len");
      }
      else {
        pgma[i].off = millis() + len * 1000;
        digitalWrite(pin, HIGH);
        Serial.println("ok");
      }
    }
  }
}

```

# Answer
> 1 votes
Using I2C (which i recommend over serial), you may not use a NodeMCU ESP8266 as a slave. It can only function as master. An Arduino, on the other hand, may be either. Therefore, the Arduino will always be passive and the NodeMCU will be the master.

What you can do, is implement a semaphore (as described by Majenko here), where the Arduino signals that it has something to "say" to the master, causing the master to request from the Arduino. It could, under these circumstances, be labeled an "obliging master" (neologism).

NEVER print to serial from inside `requestEvent` or `receiveEvent`.

---
Tags: arduino-uno, arduino-ide, i2c, esp8266
---


# Question
Title: Using Arduino to Record analog signals with SPI ADC + Sampling Rate Issue
I am using Arduino UNO to Read 8-channel, 24-bits resolution Analog signals using ADS1299 Analog-fornt-end. ADS1299 use SPI interface to talk with Arduino. Currently, I can record the analog signal with arduino based on the SPI protocol and send the data via serial port to the PC.

The ADS1299 has 8 channels with 24-bits resolutions. The sampling rate can be defined from 250s/s to 16Ks/s. As you can see in the below code, when the data is ready I put the device in reading data mode and store 8-bits (1-byte) in each run and concatenate 3 bytes to make a full sample. I repeat these procedures to obtain the whole samples of all channels. At the end I have sent a sample of one channel to the serial port using serial.print command.

Here is my problem: If I want to increase the sampling rate of device to e.g 10 Ks/s the arduino fails to provide this sampling rate due to delay produced by Serial.println command. Is is possible to store the data into a big array and then send the whole array via serial port? Is it possible that other types of microcontroller such as ARM types handle this issue? Generally how it is possible to avoid the delay of serial print?

```
    #include <SPI.h>
    #define WAKEUP 0x02
    #define STANDBY 0x04
    #define RESET 0x06
    #define START 0x08
    #define STOP 0x0a
    #define RDATAC 0x10
    #define SDATAC 0x11
    #define RDATA 0x12
    #define TESTaa 0xaa
    #define TEST55 0x55

    #define CONFIG1 0x01
    #define CONFIG2 0x02
    #define CONFIG3 0x03
    #define CH1SET 0x05
    #define CH2SET 0x06
    #define CH3SET 0x07
    #define CH4SET 0x08
    #define CH5SET 0x09
    #define CH6SET 0x0A
    #define CH7SET 0x0B
    #define CH8SET 0x0C

      const int PIN_START = 7;
      const int IPIN_DRDY = 9;
      const int PIN_CS = 10;

      const int DOUT = 12;
      const int DIN = 11;
      const int PIN_SCLK = 13;
      const int PIN_RESET = 8;

      byte chSet;
      byte chSet2;
      boolean flag = false;
      long t0, t;

    void setup(){

      // You can use serial communication for debugging
      Serial.begin(2000000);
      Serial.flush();
      delayMicroseconds(100);
      // You have to set SPI communication according to datasheet
      SPI.setDataMode(SPI_MODE1);
      //SPI.setClockDivider(SPI_CLOCK_DIV16);
      SPI.setBitOrder(MSBFIRST);
      SPI.begin();

      pinMode(DOUT, OUTPUT);
      pinMode(PIN_SCLK, OUTPUT);
      pinMode(PIN_CS, OUTPUT);
      pinMode(PIN_START, OUTPUT);
      pinMode(IPIN_DRDY, INPUT);
      pinMode(PIN_RESET, OUTPUT);

      //reset communication, see datasheet
        digitalWrite(PIN_SCLK, LOW);
        digitalWrite(DIN, LOW);
        digitalWrite(PIN_CS, HIGH);

      digitalWrite(PIN_CS, LOW); //Low to communicated
      SPI.transfer(RESET);
      digitalWrite(PIN_CS, HIGH); //Low to communicated

      // Wait longer for TI chip to start
      delay(500);
      send_command(SDATAC);
      delay(10);
      chSet = read_byte(0x00);
      Serial.println("-- ID CHIP is:" + hex_to_char(chSet) );

      // Write Config 1 and 2: see datasheet page 47
      // Config 1: Bits 7 6 5 4 3 2 1 0 --- 1 DAISY_EN=1 CLK_EN=0 1 0 DR[2:0] (110-- 250 Sample/S)  --->   0b11010110
      // Config 2: Bits 7 6 5 4 3 2 1 0 ----  1 1 0 INT_CAL=1(Int/Ext test sig) 0 CAL_AMP=(calibration signal amplitude)
      // CAL_FREQ[1:0] (calibration signal frequency)  ----->  0b11010100

      // for normal operation write to config1 0x02, config2 0xA0. For test signal write 0xA3 to config2
      write_byte(CONFIG1, 0x96);   // Daisy chain Enabled: D6 , Daisy chain Disabled: 96
      delay(10);

      write_byte(CONFIG2, 0xD1);   // Test signal Enabled: D0   Test signal  Disabpled: C0
      delay(10);

      write_byte(CONFIG3, 0xE0);   // INT Reference Enabled: E0    else  INT Reference Disabled: 60

      delay(1000);
      //this part is just to check if you send and read correct data
      Serial.println("Check Configs");
      chSet = read_byte(CONFIG1);
      Serial.println("CONFIG1: Received " + hex_to_char(chSet) );
      chSet = read_byte(CONFIG2);
      Serial.println("CONFIG2: Received "  + hex_to_char(chSet) );
      chSet = read_byte(CONFIG3);
      Serial.println("CONFIG3: Received "  + hex_to_char(chSet) );

      //remember that ch1 is used for respiration! use channel 2 for ECG measurements

       // Ch1 Setting: Bits 7 6 5 4 3 2 1 0 ---  PDn(channel power mode) GAINn[2:0] (PGA gain-- 101:  12 110 : 24)
       //SRB2 (SRB2 connection) MUXn[2:0] (channel input selection: 000 : Normal electrode input , 101 : Test signal )

       /// Input Channel Shorted  ---> 0b00000001 0X01;   Test signal Activated ---> 0b00000101 0X05;
      delay(1000);

      write_byte(CH1SET, 0x05); //
      write_byte(CH2SET, 0x05); //
      write_byte(CH3SET, 0x05); //
      write_byte(CH4SET, 0x05); //
      write_byte(CH5SET, 0x05); //
      write_byte(CH6SET, 0x05); //
      write_byte(CH7SET, 0x05); //
      write_byte(CH8SET, 0x05); //

      Serial.println("Check Channel Settings");
      chSet = read_byte(CH1SET);
      Serial.println("Ch1: Received " + hex_to_char(chSet) );
      chSet = read_byte(CH2SET);
      Serial.println("Ch2: Received  " +   hex_to_char(chSet) );
      chSet = read_byte(CH7SET);
      Serial.println("Ch7: Received  " +   hex_to_char(chSet) );
      chSet = read_byte(CH8SET);
      Serial.println("Ch8: Received  " +   hex_to_char(chSet) );

      // Start communication, you can use RDATAC or RDATA according to datasheet
      send_command(RDATAC);
      digitalWrite(PIN_START, LOW);
      delay(150);
      send_command(START);
    //  digitalWrite(PIN_CS, LOW); //Low to communicated
    //  SPI.transfer(START);
    //  digitalWrite(PIN_CS, HIGH); //Low to communicated

    }

    boolean gActiveChan [2];
    int nChannels = 1;
    int gMaxChan=1;

    void loop(){

    // Based on the Page. 36 For the 8-channel ADS1299, the number of data outputs is
    //[(24 status bits + 24 bits × 8 channels) = 216 bits].

      delayMicroseconds(10);

         if(digitalRead(IPIN_DRDY) == LOW){
          t0 = micros();

            digitalWrite(PIN_CS, LOW);

            long output[9];
            long dataPacket;
            for(int i = 0; i<9; i++){
                for(int j = 0; j<3; j++){
                    byte dataByte = SPI.transfer(0x00);
                    dataPacket = (dataPacket<<8) | dataByte;
                }

                output[i] = dataPacket;
                dataPacket = 0;
            }

            digitalWrite(PIN_CS, HIGH);
            Serial.println(output[1]);

    // t = micros()-t0;  // calculate elapsed time
   // Serial.print(1000000/float(t));
    //Serial.println(" samples per second");
    //delay(200);

     }

            }

        String hex_to_char(int hex_in) {
      int precision = 2;
      char tmp[16];
      char format[128];
      sprintf(format, "0x%%.%dX", precision);
      sprintf(tmp, format, hex_in);
      //Serial.print(tmp);
      return(String(tmp));
    }

    // see datasheet 38
    int read_byte(int reg_addr){
      int out = 0;
      digitalWrite(PIN_CS, LOW);
      SPI.transfer(0x20 | reg_addr);
      delayMicroseconds(5);
      SPI.transfer(0x00);
      delayMicroseconds(5);
      out = SPI.transfer(0x00);
      delayMicroseconds(1);
      digitalWrite(PIN_CS, HIGH);

      return(out);
    }

    void send_command(uint8_t cmd) {
      digitalWrite(PIN_CS, LOW);
      delayMicroseconds(5);
      SPI.transfer(cmd);
      delayMicroseconds(10);
      digitalWrite(PIN_CS, HIGH);
    }

    //see page 38
    void write_byte(int reg_addr, int val_hex) {
      digitalWrite(PIN_CS, LOW);
      delayMicroseconds(5);
      SPI.transfer(0x40 | reg_addr);
      delayMicroseconds(5);
      SPI.transfer(0x00);
      delayMicroseconds(5);
      SPI.transfer(val_hex);
      delayMicroseconds(10);
      digitalWrite(PIN_CS, HIGH);

    }

```

# Answer
> -1 votes
Try changing the order of these:

```
  SPI.setDataMode(SPI_MODE1);
  //SPI.setClockDivider(SPI_CLOCK_DIV16);
  SPI.setBitOrder(MSBFIRST);
  SPI.begin();

```

I think SPI.begin() needs to be started before the other two calls.

Instead of digitalWrite to control the chip select, use Direct Port Manipulation, much faster.

Does the ADC support 8 MHz SPI clock? From 7.6 & 7.7 of the datasheet, I would say yes. You can get rid of all the delayMicroseconds(5), (1), (10), as well, they are not doing anything for you.

"Unpack" this and just do 3 SPI.transfers in a row to read the data, doing it in a loop slows it down:

```
        for(int i = 0; i<9; i++){
            for(int j = 0; j<3; j++){
                byte dataByte = SPI.transfer(0x00);
                dataPacket = (dataPacket<<8) | dataByte;
            }

```

I would go so far as to do all 27 in a row even, then do the array manipulation/data combining when all 27 bytes are captured.

---
Tags: arduino-uno, spi, adc, analog-sampling
---


# Question
Title: Using Arduino as contact to the world for linux box if app crashes
I am new to this micro controller thingie world so bare with me :)

**Let me describe a scenario first.** Say I have a linux box for house automation embedded in a wall. For security reasons is **the only active access** to the box the display mounted to the wall.

**Another access would be via network and ssh but ssh is disabled.** Unfortunately does the web app sometimes crash and nothing goes. In the wake of that do I have to disassemble quite some stuff to get to the box and to revive it.

**My Idea:** I can use a nfc or rfid sensor and hook it up to Arduino. **Would it be possible to make Arduino log on to the linux box and fire up and shutdown ssh?**

I don't want to use Arduino Yun. Is it achievable with an Arduino nano/Mega?

If not, which system would be your first choice to accomplish this task?

Thanks for your patience :)

# Answer
> 1 votes
I will put our comments together in an answer.

You are overthinking the security issue. In my opinion, using RFID to reset the system is a bigger security thread, than using ssh the correct way. Normal RFID chips are susceptible to spoofing (copying an existing chip). Also the intruder could remove the RFID module to directly access the communication lines (depending on how much you will have accessible of the extra hardware). Also you can of course use the Serial interface of an Arduino to execute shell commands on your machine. You need a program on the machine to read the input and execute the commands (Majenko mentioned `agetty` for this). But is that really the best way? Using an Arduino here is a very hardware-ry way of solving a software issue. It is overly complex to do things this way and there are better options.

Instead you should really just use ssh with key-based authentication (disable password authentication). You can limit the ssh daemon to the local network (though, if you don't have configured corresponding port forwarding in your router, it isn't reachable from the internet either way), or - if you really want the additional security - to one specific device in your network. With a normal ssh key (I think 2048 bit is the standard), brute forcing is not a viable option for intruders. If you keep your private key save, there is very very little chance, that an intruder can get past that. You can also save the private key only on an USB stick, which you only use for resetting the machine. Also you can limit the commands, that the ssh user can execute, to only the resetting (like only allowing rebooting).

Depending on your actual security needs, you can choose, how far you want to go. I personally would just use key-based ssh limited to the local network. That should be plenty enough security and would also give you the possibility to access the machine, that is running in your home easier.

---

Or, if you really don't want to open ssh for the machine, you can write a simple watchdog program, that can run on the machine. Since the webapp is failing, you can write a simple python program (or any other language you like), which is regularly loading the webapp (how exactly depends largely on the webapp and the exact type of failure - may be a simple HTTP GET request) to check, if it is still alive. If the liveliness test fails for a defined number of times (let's say 3), it will reboot the machine.

This method does not require any access to the machine, but you will have to develop the liveliness test. Writing the program is then really simple.

---

All that said, it is not a good sign, that the app fails that often. You didn't write, what app that is, and what exactly fails. Maybe you are able to fix that issue directly. Or the developer of the app can, so maybe raise an issue on his platform (where the project is hosted).

---
Tags: rfid, linux
---


title: Udp.endPacket fails

text:
# Question
Title: Udp.endPacket fails
I am trying to send measurements over UDP, but the function Udp.endPacket continuously fails.

I use an Arduino Uno WiFi rev 2, WiFiNINA library version 1.4.0 and WiFiNINA firmware version 1.2.1 which seems to be the latest available.

WiFi connection setup works, obtaining a correct IP address in the 192.168.3.0/24 network.

This is a snippet of my code:

```
const char* udpDestIP = "192.168.3.126";
const int udpDestPort = 1844;
WiFiUDP Udp;

void loop() {
  // establish variables for distance result:
  long cm;

  // execute measurement
  cm = measureDistance();

  // check for false measurements and repeat if necessary
  if(minDist < cm && cm < maxDist) {
    Serial.print(cm);
    Serial.print(" cm");
    Serial.println();

    // Check WiFi connection and reconnect if necessary
    if (WiFi.status() != WL_CONNECTED) {
      connectToWifi();
    }

    // Send over UDP
    //if(!Udp.beginPacket("192.168.3.255", udpDestPort)) {
    if(!Udp.beginPacket(udpDestIP, udpDestPort)) {
      Serial.println("beginPacket fail");
    }
    String msg = "water_distance:";
    msg += cm;
    byte size = Udp.write(msg.c_str(), msg.length());
    if(DEBUG){
      Serial.print("Sending this message over UDP: ");
      Serial.println(msg);
      Serial.print("udp write: ");
      Serial.println(size);
    }
    if(!Udp.endPacket()) Serial.println("endPacket fail");

    delay(delayTime);
  }
}

```

Terminal output is as follows:

```
151 cm
Sending this message over UDP: water_distance:151
udp write: 18
endPacket fail
151 cm
Sending this message over UDP: water_distance:151
udp write: 18
endPacket fail
33 cm
Sending this message over UDP: water_distance:33
udp write: 17
endPacket fail
34 cm
Sending this message over UDP: water_distance:34
udp write: 17
endPacket fail
153 cm
Sending this message over UDP: water_distance:153
udp write: 18
endPacket fail

```

Which makes me conclude the beginPacket, and udp.write functions are executed correctly, but I see no reason why the endPacket function keeps failing. Does anyone have an idea? Thanks a lot.

# Answer
The Arduino Ethernet and WiFi library implementations require to specify the outgoing port with UDP.begin(port) before calling UDP.beginPacket().

But UDP.begin(port) starts listening for UDP messages on this port too, so it is not a clean API. Call UDP.end() to stop listening for incoming messages.
> 1 votes

---
Tags: networking, arduino-uno-wifi
---


# Question
Title: I am working on a thermometer and humidity why am i getting this error
Arduino: 1.8.9 (Windows 10), Board: "Arduino/Genuino Uno"

In file included from C:\Users\Admin\Documents\Arduino\libraries\DHT-sensor-library-master\DHT\_U.cpp:15:0:

C:\Users\Admin\Documents\Arduino\libraries\DHT-sensor-library-master\DHT\_U.h:36:29: fatal error: Adafruit\_Sensor.h: No such file or directory

compilation terminated.

exit status 1 Error compiling for board Arduino/Genuino Uno.

This report would have more information with "Show verbose output during compilation" option enabled in File -\> Preferences.

# Answer
This indicates your IDE is missing the "Adafruit Unified Sensor" library as outlined here.

To install it, select "Tools" -\> "Manage Libraries" and search for "Adafruit Unified Sensor". You can install the library by selecting it and pressing "Install".
> 1 votes

---
Tags: arduino-uno
---


# Question
Title: Powering two stepper motors with A4988 drivers
New to this site and wanted advice and sanity checking on my project design. I know there are similar questions to this but I couldn’t find one that was closely similar to mine.

I’m creating a device the uses two NEMA 17 stepper motors (https://www.omc-stepperonline.com/nema-17-stepper-motor-bipolar-l48mm-w-gear-raio-1001-planetary-gearbox-17hs19-1684s-pg100.html) with chunky 100:1 gearboxes in addition to using 1/16 microstepping. The end result of this is to achieve a stepper motor that turns very slowly (minutes per revolution).

Each motor is rated at 2.8V and 1.68A per phase (3.36A total since two phase) and I’m using an A4988 driver for each of them (https://www.amazon.co.uk/gp/product/B07FKXXJ41/ref=ppx\_yo\_dt\_b\_asin\_title\_o00\_s00?ie=UTF8&psc=1) (note that these are Chinese versions where RCS = 0.1Ω). Since the A4988 drivers are limited to 1A without additional cooling, I’ve used the onboard potentiometer to reduce Vref to just below 0.9V to prevent overheating (using the equation Vref = 8 x Imax x RCS from Pololu).

This should mean that consequentially the torque output from each motor is reduced by a factor of 1/(3.36) = 0.3 (as torque α current) since each motor is only being supplied with 1A (which is not an issue due to the large gearing ratio giving a suitable output torque). I think 1/16th microstepping might also reduce the torque slightly, but I couldn’t find any conclusive sources that didn’t contradict each other on this.

This gives a power requirement of 2.8 x 1 = 2.8W per motor, hence 5.6W in total. So, I plan to use a power source that provides at least 3A (surplus on the 2A required by the drivers) and rated at a voltage of 12V-24V to run the stepper motors. I’m also aware that I need to make sure I power the drivers in parallel from this source, and not in series to reduce strain / overheating.

I’ve included two power sources I was thinking of using:

1: 24V, 4A, 96W Desktop Switching Power Supply (https://www.amazon.co.uk/DTK-Charger-90-240V-Switching-Transformers/dp/B07K85GJ54/ref=sr\_1\_1\_sspa?crid=362Z7XFFLAYLL&keywords=24v+3a+dc+power+supply&qid=1565084176&s=electronics&sprefix=24V+3A+dC%2Celectronics%2C124&sr=1-1-spons&psc=1&spLa=ZW5jcnlwdGVkUXVhbGlmaWVyPUFHM1hUTjRTOUhYVDcmZW5jcnlwdGVkSWQ9QTA5NzA5MzQzM09IT05IR1JITEpQJmVuY3J5cHRlZEFkSWQ9QTA0NjgyMTUyQjY0UEYzRFI5OVBFJndpZGdldE5hbWU9c3BfYXRmJmFjdGlvbj1jbGlja1JlZGlyZWN0JmRvTm90TG9nQ2xpY2s9dHJ1ZQ==)

2: 24V, 15A, 360W PSU Transformer Adaptor (https://www.amazon.co.uk/NEWSTYLE-Universal-Regulated-Switching-Transformer/dp/B0758BNMLH/ref=sr\_1\_3?keywords=PSU+24V&qid=1565084433&s=electronics&sr=1-3)

Overall question is: would either of these power supplies be suitable, I think the second might be a bit overkill but i'm not sure.

Here’s the circuit diagram for reference:

Apologies for the long post, just needed to get all the information out of my head. I’m curious to see if I’ve made any errors in my calculations / assumptions, so any help is greatly appreciated.

# Answer
> 0 votes
Both power supplies are suitable.

The actual 12V/24V current required is not comparable to what the driver current is set at, since the stepper motor coils do not have those 12V/24V across them.

My first 3D printer came with a 12V 5A power supply, which proved suitable for simultaneous use of four stepper drivers, the control board, a display, and the heater cartridge (40W).

---
Tags: arduino-uno, power, stepper, a4988
---


title: Arduino Mega TIMER1 one second interval

text:
# Question
Title: Arduino Mega TIMER1 one second interval
Is this timer set correctly for Arduino Mega? It should count exactly one second. And why when I print in serial monitor (seconds\_passed++) is it incremented by 2 not by 1?

Full code on Pastebin: LINK

```
noInterrupts();
//set and initialize the TIMER1

TCCR1A = 0; // set entire TCCR1A register to 0
TCCR1B = 0; // set entire TCCR1B register to 0
TCCR1B |= (1 << CS12);
TIMSK1 |= (1 << TOIE1);
TCNT1 = 3036;

attachInterrupt(digitalPinToInterrupt(ignition_pin), ignitionSignal, CHANGE);
interrupts();

ISR(TIMER1_OVF_vect) {
  //TIMER1 overflow interrupt -- occurs every 1sec --
  instantSpeed();
  LPG_Consumption();
  LPG_injector_open_duration = 0;
  unleadedConsumption();
  unleadinj_Open_Duration = 0;
  seconds_passed++;
  vss_pulses = 0;
  TCNT1 = 3036;
}

```

# Answer
Your timer configuration is ok so far. Never the less I recommend using the `TIMER1_COMPA_vect` interrupt vector instead of `TIMER1_OVF_vect` which has the advantage of better readability (in my oppinion) and `TCNT1` doesn't have to be reset in the ISR (instead, OCR1A is just initialized with 62500 once in `setup()`). Therefore, TIMER0 has to run in CTC (clear timer on compare match) mode and `WGM12` has to be set in TCCR1B.

The reason why `seconds_passed` is incremented twice is because you `Serial.print(seconds_passed++)` in `instantSpeed()`. Printing on the serial interface is damn slow and using it in an ISR is a no-go!
> 1 votes

---
Tags: arduino-mega, timers, code-review
---


title: Arduino detect order of objects

text:
# Question
Title: Arduino detect order of objects
I'm trying to find a way to detect blocks being placed on grid on a table. The table will have fixed places where you can place the blocks, but the user is allowed to place the blocks in any free slot. I would like to have an Arduino poll the slots on the table and tell me which blocks are placed where.

I'm going to design the blocks with magnetic connections on the top and bottom to create a circuit as soon as they are placed.

What kind of chips can I use so that the arduino can give me the topology of the blocks when placed?

# Answer
You need to track unique objects in an 8x8 grid of slots? How many unique objects?

If the total number of objects is 112 or less, you could give each one a unique I2C address.

You'd add 4 circular electrical contacts in a "bulls-eye" configuration on the top and bottom of each object so that all the I2C pins would connect regardless of orientation. All objects in the same stack would be connected together on that stack's I2C bus.

You'd have an 8x8 multiplexer to connect to the I2C bus for each of your 64 grid positions in turn, and poll that bus for each of the possible I2C addresses. (Send a ping for each address and look for `ACK`s.)

---

Alternately, you could give every object a unique weight, varied by a power-of-two amount. (first object weighs 1000 grams. Second weighs 1001 grams (1000+2^0)) third object weighs 1002 grams (1000+2^1). Fourth object weighs 1004 grams (1000+2^2). Etc.)

Then you'd put a scale on each pad. Weigh the objects, modulo 1000 grams. That result, in binary, would give you flags for every object on that pad.

---

Or 2 circular electrical contacts on the top and bottom of each object, with resistors that have unique power-of-two resistance on each one, as Juraj suggests in their comment. Measure the resistance and you can figure out which set of objects is present.

The math would be simpler if you rigged the objects so that they made a series circuit through all objects present (put a normally closed switch on the top that shorts the top contacts of that object through its resistor if there's no object on top of it. If there is an object, the switch would open, and the objects on top would close the circuit.)
> 0 votes

---
Tags: i2c, communication
---


# Question
Title: Arduino UNO and RS485 Communication Problem
I am learning Arduino, a beginner in programming. I want to use Arduino UNO to connect a wind direction sensor RS485. The problem is the output in the serial monitor, the return data from the wind direction sensor is unstable.

I need to get the return data from the wind direction sensor to get the wind direction. From the factory manual, they said sent a data to the sensor: 0x01 0x03 0x00 0x00 0x00 0x02 0xC4 0x0B and the sensor will return, like 0x01 0x03 0x04 0x06 0x48 0x00 0xA0 0x7A 0xD5

The wind direction dat at the above 5 and 6 position, the 0x00 0xA0 =\> 00A0H(HEX)=160 degree.

**Tools:** Arduino Uno Board

Wind Direction Sensor http://www.jnrsmcu.com/equipment/299.html

RS485 Board (3.3V) https://www.waveshare.com/rs485-board-3.3v.htm

**The following is my coding:**

```
#include <SoftwareSerial.h>

SoftwareSerial RS485Serial(10, 11); // RX, TX

void setup()
{
    RS485Serial.begin(4800);   // set the data rate
    Serial.begin(4800);
    Serial.println("Start");

    pinMode(12, OUTPUT);
    digitalWrite(12, HIGH);  // Init Transceiver
}

byte buf[8];

int byteReceived;

void loop()
{
    digitalWrite(12, HIGH);

    byte wind[] = {0x01, 0x03, 0x00, 0x00, 0x00, 0x02, 0xC4, 0x0B};
    RS485Serial.write(wind, sizeof(wind));
    Serial.flush();
    RS485Serial.flush();
    // Serial.print(wind[0], HEX);
    Serial.println("Send");

    digitalWrite(12, LOW);
    delayMicroseconds(200);

    RS485Serial.readBytes(buf, 8);
    delay(10);
    Serial.println(buf[0], HEX);
    Serial.println(buf[5], HEX);
    Serial.println(buf[6], HEX);
    Serial.flush();
    RS485Serial.flush();
    delay (1000);
}

```

**Connection map:**

# Answer
> 1 votes
I would suggest you simplify your setup to the point where you have a 'working baseline configuration', and then start building the system up one step at a time from there.

Start by eliminating the SoftwareSerial interface as a possible contributor to the problem. Get an Arduino Mega with multiple hardware serial ports.

Next, verify that you can send characters to the selected hardware serial port and receive those same characters back when the Txn and Rxn lines (the 'n' here is the selected hardware serial port number) are connected via a jumper wire. This is called a 'loopback' configuration and is a basic serial comms troubleshooting technique (software serial ports don't support simultaneous transmit and receive, so they don't support loopback testing). Don't proceed until you have this step completed successfully.

Next, get a second RS-485 module and extend your previous 'loopback' configuration with the hardware serial port on the Mega to include the two RS-485 modules. Then you should be able to send characters out to one RS-485 module and receive the same characters back from the other, by connecting TXn to DI on one of the two RS-485 modules, and Rxn to DO on the other.

At this point you will have verified all the communications connections, so you can be confident that whatever you send will actually show up at the DO port of the RS-485, and whatever shows up at the DI port of the RS-485 will actually make it back to your serial console. Now you can connect the sensor and figure out any issues do to data formatting, command sequences, and the like.

This basic 'cut the problem in half' building block technique will work on any system, large or small, simple or complex.

Frank

# Answer
> 0 votes
* I don't see any connection between the sensor's GND and your Arduino's. This is likely the problem if they're not connected, since a common GND is necessary even with RS-485.
* Check the sensor's power supply, make sure it's actually within the advised 10-30 V range. Also check the polarity of the differential lines.
* Have you tried using the provided configuration software?
* `flush()` does nothing for `SoftwareSerial` ports since they have no TX buffer, so you can just get rid of those lines, including the unnecessary `Serial.flush()`
* Finally, your device datasheet says to wait for at least 200 *milliseconds* not microseconds, before checking for a response. Though it really shouldn't matter since you're using `readBytes()` after that, which waits for a second anyways by default, before giving up. Instead, use a bigger buffer, say 20 bytes, then try to read just 8 (the expected length) into it with `readBytes()`:

```
byte buf[20];
int rlen = RS485Serial.readBytes(buf, 8);

```

Then try to print `rlen` which tells you how many bytes were actually read and also print the whole response to verify the packet format is as it should be. You should get enough info from this to at least eliminate a bunch of possible problems.

---
Tags: arduino-uno, rs485
---


# Question
Title: How do I upload an Arduino STM32 binary from the Mac command line?
I've compiled an Arduino program via a Makefile and have the resulting hex file.

From the Mac command line, how do I upload this hex file to my STM32 Cortex M3 board? For an ATMEL processor I would use avrdude.

# Answer
There are several different tools for uploading binaries to a Cortex M3. Depending on the board (not chip) configuration, they include (ht: Majenko):

* dfu-util through an FT232 adapter
* stm32flash through serial
* micronucleus through the Micronucleus bootloader
* stlink through an STLink programmer

Many Arduino flavors use a board with some kind of USB or FT232 adapter. In this case:

the STM32 line of processors include a DFU (device firmware update) bootloader in ROM.

The dfu-util project supports a Mac version of dfu-util, their command line DFU tool.

Note that this answer is identical for any binaries which run on the processor, be they Arduino sketches or programs developed with other frameworks.
> 1 votes

---
Tags: uploading, mac-os, command-line
---