Programing a Bare Pic32 I recently received two types of Pic32 microcontrollers from Microchip, specifically the PIC32MX270F256B and the PIC32MX230F256B. I would like to use an Arduino Uno to setup the bootloader and to do all the programming. I found a tool to upload to the board here, but as it is from a 2012 forum here, I cannot figure out what it is exactly used for. It seems to be able to upload hex files, but in which format and to what is unclear to me. I also found Arduino bootloaders for a similar group of microcontroller here, however I cannot tell exactly which version I need, if any, or how to upload it.

Any help on how to use these tools or others would be greatly appreciated as my only experience with Arduino before this is with a simple to program to Arduino Uno.

I am unaware of any Arduino-based tools for installing a bootloader on a PIC32. If you are going to work with PIC32 you really should invest in a proper programmer.

I often use (pretty much throw-away) Chinese clones of the PICkit2 programmer. You can find them on eBay nice and cheap.  Genuine Microchip programmers are pretty expensive, so these cheap clones are quite handy...

You will also want to install the chipKIT environment into the Arduino IDE.

When it comes to the bootloader there are no official boards that use those chips. So you will need to compile your own version, which is not trivial. You will need to install MPLAB-X and the XC32 compiler and create a new profile within the project with the right settings for your board.

And then of course you will have to craft a board configuration for your custom board.

All-in-all it's quite a complex task porting a new board / chip to the chipKIT environment, and you would probably be better off directly using MPLAB-X and programming directly in C (although it's harder to get started in that environment). The PIC32 chips are considerably more complicated to work with than little AVR chips.


Convert a Double to an UnSigned Char So, I'm working on RedBear Blend Micro V 1.0, and I must use the function:

ble_write(Serial.read());

To read some input from the serial monitor(Input being stuff I type in the Serial Monitor) and send it via bluetooth.
It works perfectly this way!

Now what I need to do is create a random double data type number, and insert it in the place of Serial.read()

Read This:

ble_write

Syntax:
    void ble_write(unsigned char data);
  ble_write sends a single byte data to the BLE Central.

So, can you please help me, to:

1)Generate a random double

2)Send it using the ble_write() function?

For a full list of function sin the ReadBear Library click on the link:
https://github.com/RedBearLab/nRF8001

Edit: Chris Stratton rightfully points out that the question is
about a double, not a float:

a float is four bytes in every platform I know about, as per the
IEEE-754 standard
a double is eight bytes in almost all platforms, with the notable
exception of AVR: the AVR double is highly non-standard, four bytes
long, and essentially equivalent to float

Most, but not all Arduinos, are AVR-based.
In the following I assume you are talking about AVR doubles, i.e.
floats. If this is not the case, then just replace the array of 4 bytes
by an array of 8 bytes.

Original answer:
A float is four bytes, so it is somewhat equivalent to an array of
four unsigned chars, i.e. to unsigned char[4]. You can use this
equivalence with an union. For example, the following function will
send a float byte by byte:

void ble_write_float(float x)
{
    union {
        float f;
        unsigned char c[4];
    } data;

    data.f = x;
    ble_write(data.c[0]);
    ble_write(data.c[1]);
    ble_write(data.c[2]);
    ble_write(data.c[3]);
}

Notice that this will send the bytes in whatever is the natural order of
the sending processor. If it's an AVR (like most Arduinos), this will be
LSB (least significant byte) first. You have to make sure that this is
what the receiver expects.

Following Ignacio Vazquez-Abrams' suggestion, for sending a random float
you could just send four random bytes. However, it may be wiser to have
an idea of the random distribution you want for your float, and use
things like random() and map() to achieve that distribution. Using
four random bytes, you get a very wide distribution (all the possible
floats are equally likely) which includes weird things like denormals,
infinities and NaN (literally meaning “not a number”).


Getting maximum value from HX711 and use it in the code further i am using HX711 module to get value from load cell.my projects is a tensile strength testing machine,which will increase the load gradually and break at its maximum capacity.therefore i need the maximum value at which the specimen breaks.and use that value in the code to calcuate the tensile strengh of the specimen using the formula(tensile strength=load/cross section area of specimen).
Please help me with this and if possible ,i will be very gratefull if anyone can help me with the code too.
Thank you

We won't write the code for you, since we are not a free coding service, but I will try to give you some hints, how you can do it.

Timing of measurements: The measurements themselves can be done with one of the HX711 libraries, that are available on the web, but you may want to time them to get more regular measurements. This can be done in a non-blocking coding style like in the BlinkWithoutDelay example, that comes with the Arduino IDE. It involves the millis() function to measure the time since the last measurement and act accordingly. This is explained many times troughout the web and on this site.
Saving the data and finding the maximum: This depends on what else you want to do with the data.

Saving all data for later processing: You might want to save all data (the load curve) for later use. In this case you have to define an array of appropriate length (the length depends on the duration and frequency of the measurement). Also define a position variable or pointer, that marks the current position in this array. Everytime when you do a measurement, you save the result to the array element at the saved position and increment the position variable after that. After the end of the measurement, you declare a value variable with the value of the first array element. Then you loop through all the following elements (for(int i=1;i<array_length;i++)). Inside the loop you calculate and save the maximum of 2 numbers: The value of the current array element and the saved variable. This can be done with saved_value = max(saved_value, array[i]);. When the loop is finished, you will have the maximum value in the saved_value variable.
No saving of data: You can also calculate a flying maximum without saving all data. Declare a variable (max_value), that will hold the maximum value, and set it to zero. Then, everytime when you do a measurement, you execute max_value = max(current_value, max_value); which calculates the maximum of the two numbers (current measurement and the previously calculated maximum). At the end of the measurement you will have the absolute maximum in the max_value variable.

Sensing the end of measurement: You need to sense the end of the measurement (when the specimen breaks) (though this can be done manually if you like). For this I would suggest to calculate the speed in which the load changes. During the measurement the load will increase slowly. In the moment of breaking the load will decrease very fast. The speed between two load measurments is calculated by (value(x) - value(x-1))/measurement_interval. You can define a threshold of negative speed, so that every speed below it (faster negative decrease of load) will be sensed as breaking of specimen. You can check this on every measurement with a simple if statement, or you can calculate the speed over more than 2 consecutive measurements. That depends on the actual speed of load change and the frequency of load measurements.
Calculating the tensile strength: This is just writing your formula into the code using the variable names, that you used in the previous code. Be sure to use the correct variable type for your needs. Most likely you would want to use float.
Getting input from user: This depends largely on your planned means of interaction with the user. Is the Arduino connected to a PC and you use a serial terminal program? Then you can use this for user input (You might want to look at the SerialEvent example of the Arduino IDE, which shows how to work with messages and delimiter characters). Do you want to add a keypad and a LCD display? There are library available for these too, so it should not be very difficult to learn how to use then to get user input.


Can I use a PIR sensor to turn on an arduino? I'd like to use a PIR sensor (HC-SR501) to control the power to an Arduino Uno. Note that I'm not talking about using a PIR sensor as input to the Arduino and sensing the output pin from the PIR, I'm talking about using the output pin from the PIR to turn the Arduino itself on and off.

Hooking it up directly doesn't seem to work as I'm guessing the PIR doesn't handle that much current output. Would I use a transistor of some kind to do this?

My reason for wanting to do this is simple, power preservation. The PIR uses so little current when it doesn't sense anything that I thought it would be nice for something like a mailbox sensor that doesn't need to run that often. Thanks.

Yes you can.

It all depends on how you are turning the power on.  You sensor needs to flip a 'switch' rather than actually power the Arduino directly.  (I'm sure you know that but just in case).

So you need a normally open relay in between you power source and you Arduino.  Normally open because you don't want it powered unless you 'turn it on'.  Your relay might be able to be switched by your PIR sensor's data output, but if you need more current then you are going to have to use a transistor and draw more power from the power source.

You have the PIR sensor, so now find the relay capable of carrying the maximum current you need for the Arduino.


PIR sensor code logic works on Mega but not on Yún I am trying to use this example(it works on Arduino Mega): millis() - lowIn comes greater than 5000when motion ends.

/////////////////////////////
//VARS
//the time we give the sensor to calibrate (10-60 secs according to the datasheet)
int calibrationTime = 30;

//the time when the sensor outputs a low impulse
long unsigned int lowIn;

//the amount of milliseconds the sensor has to be low
//before we assume all motion has stopped
long unsigned int pause = 5000;

boolean lockLow = true;
boolean takeLowTime;

int pirPin = 3; //the digital pin connected to the PIR sensor's output
int ledPin = 13;

/////////////////////////////
//SETUP
void setup() {
  Serial.begin(9600);
  pinMode(pirPin, INPUT);
  pinMode(ledPin, OUTPUT);
  digitalWrite(pirPin, LOW);

  //give the sensor some time to calibrate
  Serial.print("calibrating sensor ");
  for (int i = 0; i < calibrationTime; i++) {
    Serial.print(".");
    delay(1000);
  }
  Serial.println(" done");
  Serial.println("SENSOR ACTIVE");
  delay(50);
}

////////////////////////////
//LOOP
void loop() {
  if (digitalRead(pirPin) == HIGH) {
    digitalWrite(ledPin, HIGH);
    //the led visualizes the sensor's output pin state
    if (lockLow) {
      // makes sure we wait for a transition to LOW before any further output is made:
      lockLow = false;
      Serial.println("---");
      Serial.print("motion detected at ");
      Serial.print(millis() / 1000);
      Serial.println(" sec");
      delay(50);
    }
    takeLowTime = true;
  }

  if (digitalRead(pirPin) == LOW) {
    digitalWrite(ledPin, LOW);
    //the led visualizes the sensors output pin state
    if (takeLowTime) {
      lowIn = millis();
      //save the time of the transition from high to LOW
      takeLowTime = false;
      //make sure this is only done at the start of a LOW phase
    }
    //if the sensor is low for more than the given pause,
    //we assume that no more motion is going to happen
    Serial.print(millis() - lowIn);
    Serial.print("    ");
    Serial.print(lockLow);
    Serial.print("    ");
    Serial.println(pause);
    if (!lockLow && millis() - lowIn > pause) {
      //makes sure this block of code is only executed again after
      //a new motion sequence has been detected
      lockLow = true;
      Serial.print("motion ended at "); //output
      Serial.print((millis() - pause) / 1000);
      Serial.println(" sec");
      delay(50);
    }
  }
}

But it doesn't work on a Yún shield mounted on an Arduino Leonardo. The difference of millis() - lowIn always comes out to be lower than pause.

The Arduino Leonardo uses the ATmega32U4 microcontroller which uses lower logic levels for the digital inputs. Perhaps that is not compatible with the PIR sensor. You can simulate the PIR sensor with a piece of wire and connect it to 5V or GND.

For the Leonardo, sometimes "SerialUSB" is used instead of "Serial". But if see a message on the serial monitor then "Serial" is okay.

If you can't make it work, then try to reduce the number of variables. In this case, remove the Yun shield and try it with the Leonardo board.

The Arduino Mega 2560 and Arduino Leonardo have both a 8-bit microcontroller and 'millis' works on both in exactly the same way. Therefor 'millis' itself or the variables can't be the problem.


Sound sensor signals with time bracket I've tried many codes for this to work but anything isn't helping at all, so my code should work like this: If a sound sensor (3 pins, A2) sends 5 signals into the Arduino within 10 seconds (the time gap of every signal varies, but doesn't matter as long as it sends 5 signals), the LED (13) will light up. This is my recent code if it could help

int led=13;
int sensor=A2;

void setup()
{
   pinMode(led, OUTPUT);
    pinMode(sensor, INPUT);
    Serial.begin(9600);
}

void loop()
{
    unsigned long StartMillis = millis();
    unsigned long CurrentMillis = millis();
    int signal_count=digitalRead(sensor);
    int signal_limit=5;
    Serial.println(signal_count);

    while ((CurrentMillis - StartMillis)==5000)
    if (digitalRead(sensor)=0)
    {     signal_count ++;
        Serial.println(signal_count);
    }
    if (signal_count>signal_limit) {
        digitalWrite(led, HIGH);
    }
    else {
    digitalWrite(led,LOW);
    }
}

Your handling of millis() is wrong. With these two lines:

unsigned long StartMillis = millis();
unsigned long CurrentMillis = millis();

StartMillis will always have the same value as CurrentMillis. (Ok, I guess its possible for millis() to return a value that's increased by 1 the second time it's called, but that is extremely unlikely. The 2 lines takes much less than a millisecond to execute.)

Your

while ((CurrentMillis - StartMillis)==5000)

will never evaluate to true, so the code in the while block will never execute.

This if statement is also wrong:

if (digitalRead(sensor)=0)

You want == (comparison) not = assignment. I'm surprised the compiler even allowed that to compile, since you are trying to set the function digitalRead(sensor) to 0, which doesn't make sense.

Change that code to read:

if (digitalRead(sensor)==0)

(Assuming you want the body of the if statement to execute when your sensor value is 0.)


I am planning to do a periodic table with Arduino's help but I have a few questions I'm doing that for my school project, but I have few questions before I purchase the components.

First of all, let me explain how it will work:

There will be 4x20 LCD, an Arduino and probably two potentiometers (due to the potentiometer's sensitivity). When the user turns the potentiometers, the program adds the first potentiometer's value to the other potentiometer's value, because of sensitivity issues. Then the program checks which element corresponds to the two potentiometers' values.

After that, the program shows that element's information in the LCD (like its name, symbol, neutron number, proton number, valence electrons, ...).

Questions:

There are around 118 elements in the periodic table. I'm not an expert with programming, but this means there will be 118 if ... else if ... statements. I can shorten the inside of the if statement by function, but there will be still 118 if statements. I'm afraid it will be over the memory (sketch size limit) limit of the Arduino. How can I shorten the code?
Should I buy a Mega or will a Uno be enough?
Will there be any problems if I connect a 5V Arduino pin to both potentiometers and 4x20 backlight? If not, how can I fix this? I don't want to use any other power source except Arduino.

Expanding an answer from my comment on your question:

First thing is to define a struct that holds all the data you want to
store and display for one element:

struct Element {
    char symbol[3];
    char name[16];
    float mass;
    char electronic_state[9];
    // etc...
};

Do not store the atomic number, as it will be deduced from the index on
the array you will build. Each string in this struct (symbol, name...)
should be big enough to store the longest possible string, including the
final NULL terminator. The compiler will help you here: if you do not
allocate enough room, it will later say something like “error:
initializer-string for array of chars is too long”.

It is obviously somewhat inefficient to allocate each string the maximum
possible length. I suggest you do this for the sake of simplicity, and
because I do not think you should be short on flash, even on an Uno. If
you really end up being short on flash, then I suggest you seriously
consider jwpat7's answer. It is somewhat complicated, but likely to be
significantly more efficient than mine in terms of flash usage.

Second step is to write down the periodic table as a PROGMEM array:

const Element periodic_table[] PROGMEM = {
    // symbol  name    mass      electronic state
    {"H",  "Hydrogen", 1.008,    "1s1"     },
    {"He", "Helium",   4.002602, "1s2"     },
    {"Li", "Lithium",  6.94,     "[He] 2s1"},
    // etc...
};
const size_t table_length = sizeof periodic_table / sizeof *periodic_table;

Then your program will only have to browse through this table in order
to get the needed information. The only tricky part here is that you
will have to copy the data to RAM before using it, for example with
something like:

Element elt;  // element in RAM
memcpy_P(&elt, &periodic_table[i], sizeof elt);

I do not have an LCD, so I wrote a test program that simply dumps the
table through the serial port:

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

void loop()
{
    Serial.println(F("Z  Symbol  Name  Atomic mass  El. state"));
    Serial.println(F("---------------------------------------"));
    for (size_t i = 0; i < table_length; i++) {
        Element elt;  // element in RAM
        memcpy_P(&elt, &periodic_table[i], sizeof elt);
        Serial.print(i+1);  // Z = i+1
        Serial.print(F("    "));
        Serial.print(elt.symbol);
        Serial.print(F("     "));
        Serial.print(elt.name);
        Serial.print(F("  "));
        Serial.print(elt.mass);
        Serial.print(F("  "));
        Serial.println(elt.electronic_state);
    }
    Serial.println();
    delay(1000);
}

This program only takes 4480 bytes of flash. This means I could expand
the table to 118 elements and over 200 bytes of data per element before
running out of flash on an Uno.


How to burn bootloader and upload sketches on custom arduino? Ive turned a project I breadboarded with arduino and other modules into one pcb on EAGLE. The pcb includes the ATMEGA328p smt version that doesn't have the bootloader installed. My question is then what module or components can I use to burn the bootloader onto the atmega and upload programs to it together?

You can use a second Arduino as a standalone programmer for it, either to upload your sketch directly, or to upload a bootloader (after which you'd upload your sketch in the normal way). The example program, ArduinoISP, uploaded into the second Arduino is what can do this. Here is a link to a how-to article for doing just that.

If you haven't already populated your PCB, good - sometimes your external (to the MCU) circuitry can interfere - but it's worth a try, even if you have.


How to flush the input serial buffer in Arduino? I am communicating with the esp8266 WiFi module using Arduino. The module returns GET requests from other clients. They will be of the form

GET /101011 HTTP/1.1\r\nHost...

I wish to extract only the 101011 from the received serial data and discard the rest. I came up with this small chunk of code to test it by sending data from my laptop.

This is the code:

String s;

void setup() {

  Serial.begin(9600);
}

void loop() {

  if(Serial.available())
  {
    Serial.println("Inside");
    Serial.find("/");
    s = Serial.readStringUntil(' ');
    Serial.println(s);
    // Discard the rest of the data . Snippet from Jeremy Blum's Blog

    while(Serial.available()>0) Serial.read();

  }

}

Jeremy's Blog

But when I run this using the input GET /101011 HTTP/1.1\r\n the output produced is

Inside
101011
Inside
1.1\r\n

Why is Serial.available() returning true even after reading everything? How to discard the rest of data from the serial input buffer?

One possible approach is to read and discard everything for a fixed time, like a second. For example:

unsigned long now = millis ();
while (millis () - now < 1000)
  Serial.read ();  // read and discard any input

I'm not a big fan of trying to "flush the input buffer". How do you know if a second is long enough? Or maybe it is too long? You are better off reading to some known delimiter.


Are there any products based on Arduino that are sold by companies? Ok, Arduino is a good technology but is it used professionally? Is the quality good enough to be used for professional purposes?

In theory, an Arduino board could be used in some low-end professional products (i.e. where the performance and memory limitations aren't an issue). The build quality of the official boards is certainly good enough. The only issue they would potentially have is making suitably robust connections -- i.e. anything plugged into a female header would have the potential to get shaken loose.

In practice though, using an Arduino board would only make sense for extremely small-scale projects, where only a few units will be produced, and where there will be a minimum of external circuitry.

A commercial project would normally have a custom circuit board designed. That allows them to economise on space and features, eliminating unnecessary costs. Even if it only saves a small amount per board, it can make a big difference if you're doing mass-production.

With that said, a professional product could certainly use an AVR microcontroller or similar at its heart (much like the Arduino boards). Atmel was producing chips long before Arduino was around, and their products are well known and widely used. The choice really depends on the needs of the individual project.


Dynamically create functions for AccelStepper that use Adafrut_StepperMotor.oneStep methods? In the Adafruit_MotorShieldV2Library>Accel_MultiStepper example, AccelSteppers are initialized using the following static forwardstep1 and backwardstep1:

#include <Wire.h>
#include <AccelStepper.h>
#include <Adafruit_MotorShield.h>

//First, get an Adafruit_MotorShield
Adafruit_MotorShield AFMStop(0x60); // Default address, no jumpers

//Then, get a stepper motor from it
Adafruit_StepperMotor *myStepper1 = AFMStop.getStepper(200, 1);

//Then, create callbacks for the AccelStepper's constructor
void forwardstep1() {
    myStepper1->onestep(FORWARD, SINGLE);
}
void backwardstep1() {
    myStepper1->onestep(BACKWARD, SINGLE);
}

//Finally, create the stepper motor
AccelStepper stepper1(forwardstep1, backwardstep1);

I intend to then use these AccelSteppers as members in a MultiStepper, which I'm skipping here because it shouldn't be relevant.

I want to make a function that automates this process. Ideally it would work something like this:

typedef void(*mover)();
AccelStepper makeStepper(Adafruit_StepperMotor myStepper){
    // create functions of type mover
    mover forward = []{myStepper->onestep(FORWARD, DOUBLE);};
    mover back = []{myStep->onestep(BACKWARD, DOUBLE);};
    return AccelStepper step(forward, back);
}

What I've tried:

Obviously the above solution. This doesn't work because myStepper isn't captured, but if you capture it it's not a mover object and can't be passed to AccelStepper.
Using an object's function. This doesn't work because object functions have the implicit first parameter this. See this for more info
Making the parameter myStepper static after it's passed in. This doesn't work because it gets over-written on every call to the function.
Using std::forward. This would probably work, but I don't think std::forward is defined in ArduinoSTL because I keep getting the error 'forward' is not a member of 'std'. See the code below:

Note, In an attempt to make this work, I upgraded the following folders to -std=gnu++17 on my ubuntu machine, resulting in __cplusplus == 201500:

~/.local/share/umake/ide/arduino/hardware/arduino/avr/platform.txt
~/.local/share/umake/ide/arduino/hardware/hardware/platform.txt

std::forward attempt

#include <ArduinoSTL.h>
using namespace std;
#include <iostream>
#include <functional>
#include <utility>

typedef void(*mover)();

template <classF>
mover lambda_to_ptr(F&& f){
    static F fn = std::forward<F>(f);
    return []{ return fn();};
}
AccelStepper makeStepper(Adafruit_StepperMotor myStepper){
    // create functions of type mover
    mover forward = []{myStepper->onestep(FORWARD, DOUBLE);};
    mover back = []{myStep->onestep(BACKWARD, DOUBLE);};
    return AccelStepper step(lambda_to_prt(forward), lambda_to_ptr(back));
}

p.s. Of course, I could always change the functions in the library, but this is (almost) always a bad idea.

I ended up just inheriting AccelStepper, and extending the
AccelStepper::AccelStepper  (   uint8_t interface = AccelStepper::FULL4WIRE,uint8_t pin1 = 2,uint8_t pin2 = 3, uint8_t pin3 = 4, uint8_t pin4 = 5, bool enable = true ) constructor to add my own Adafruit_StepperMotor instance variable and using it in an overridden step0 (which is the only function those callbacks were used in).

class MyAccelStepper: public AccelStepper
{
   public:
       MyAccelStepper(Adafruit_StepperMotor *myStepper):AccelStepper(0,0,0,0,0,false)
       {
         //MyStepper(0, 0, 0, 0, 0, false);
         _myStepper = myStepper;
       }
   protected:
       void step0(long step){
          (void)(step);
          if(speed() > 0){
            _myStepper->onestep(FORWARD, DOUBLE);
          }else{
            _myStepper->onestep(BACKWARD, DOUBLE);
          }
       }
    private:
       Adafruit_StepperMotor *_myStepper;
};


Arduino ISP external power I want to program an atmega328p-pu via my arduino uno as ISP in a circuit.

I omitted my connected sensors, LCD, etc in the schematic to keep it simple.

When I power the circuit via a 5V power supply (left) I get

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.02s

avrdude: Device signature = 0x000000 (retrying)

Reading | ################################################## | 100% 0.02s

avrdude: Device signature = 0x000000 (retrying)

An error occurred while uploading the sketch
Reading | ################################################## | 100% 0.02s

avrdude: Device signature = 0x000000
avrdude: Yikes!  Invalid device signature.
         Double check connections and try again, or use -F to override
         this check.

avrdude done.  Thank you.

When powering off the circuit and connecting 5V and GND from the arduino to the power and gnd lines in my circuit everything works fine.

I connect 5V and GND from the arduino via pin headers I added to the 5V and GND rails in my circuit to power external sensors etc.

Is there a reason I apparently have to use power from the arduino?

Even with an external supply, you must still have a common ground reference between the ATmega being programmed, and the Arduino/ATmega doing the programming.  According to your comment this was the critical issue.

Also keep in mind that the specifications of most ICs including the ATmega prohibit applying signal voltages when the chip itself is unpowered.  To stay within that specification, you would need to turn on the external supply first, and insure that all of the pins were in their high impedance state and not driving the programmer's ATmega when it is unpowered.

Your pullup resistor on the target's reset would weakly drive pin 10 on the programmer, but a 10K resistor should limit the current to within what the protection diode on the corresponding ATmega pin can tolerate (even such a weak current can however cause problems with clean startup, though the ATmega is less sensitive than some other devices).

If you can't be sure power is going to be applied correctly, putting 1K (maybe even 2.2K) series resistors between the two chips can help a little, but there's a balance between keeping the signals strong enough to work well, and keeping illicit currents weak enough to avoid stress.


How to close/end a Wire.begin()? I have an ESP32 cam, and I attached an i2c light sensor to it. I need to read the light level at startup, then I don't need the i2c connection again.
The problem is, the board uses 2 i2c connections I think (for the camera and such). So I use my custom pins for the sensor (15 and 16). It works well, I can read the light just fine, but then the camera fails because (I believe) the Wire.begin(15,16) changes the default pins and the camera gets confused.
So I would like to do something like Wire.end() to forget that I started the Wire.begin(). Any idea on how I can do that?
Here is the relevant code:
#define I2C_SDA 16
#define I2C_SCL 15
BH1750 lightMeter (0x23);
TwoWire I2Clightmeter= TwoWire(1);

void setup()
{
  I2Clightmeter.begin(I2C_SDA, I2C_SCL);
  lightMeter.begin(BH1750::ONE_TIME_HIGH_RES_MODE,0x23,&I2Clightmeter);

  delay(1000);
  uint16_t lux = lightMeter.readLightLevel();

//rest of the code

There is a way of doing it that's ESP32 specific. However it means changing how you define your I2C object.
The ESP32 system is set up so that if the TwoWire instance is destructed the I2C bus is released. But you can't do that with the way you normally define the object. So instead you have to use dynamic allocation to control it:
TwoWire *I2Clightmeter;

void setup() {
    I2Clightmeter = new TwoWire(1);
    I2Clightmeter->begin(I2C_SDA, I2C_SCL);
    lightMeter.begin(BH1750::ONE_TIME_HIGH_RES_MODE,0x23,I2Clightmeter);
    delay(1000);
    uint16_t lux = lightMeter.readLightLevel();
    delete I2Clightmeter;
    // rest of code
}

Another alternative is to keep the TwoWire object in a local scope so that it gets destroyed when you leave that scope - maybe with a special function for it:

uint16_t getLux() {
    TwoWire I2Clightmeter(1);
    I2Clightmeter.begin(I2C_SDA, I2C_SCL);
    lightMeter.begin(BH1750::ONE_TIME_HIGH_RES_MODE,0x23,&I2Clightmeter);
    delay(1000);
    return lightMeter.readLightLevel();
}

void setup() {
    uint16_t lux = getLux();
    // rest of code
}


Does the Arduino deteriorate after shorting the voltage regulator? I mistakenly connected a 7.4V battery backwards to an Arduino Nano via the Vin pin. The Arduino still works (I can upload code) connecting it to the PC using the USB cable. Here's my question: will the Arduino deteriorate using this method or can I continue using it (I'm soon going to buy a new voltage regulator)?

Of course, if you can upload the code, you can continue to use it ;)

Even if the Arduino is cheap, it is really reliable. There are always some short circuit protections.

The Voltage Regulator (I think it is a simple LM1117) has a overcurrent protection too (see: http://www.ti.com/lit/ds/symlink/lm1117.pdf)

So, don't worry. You can continue, continue and continue to use it...

Edit: just a note: never drain more than 50mA on an output. This will destroy the pin on your Arduino.


Arduino doesnt seem to be reading my pin states I seem to have an unbelievable thing. My code was working perfectly on one arduino, when i upload the same sketch to another one, it is behaving strangely, it seems like it is not reading any of my pin states:

The code is ment to drive a simple stepper motor with driver. depending on the state of several pins in which direction it moves or moves at all.

What is happening now is when i upload the sketch the motor starts to turn, nomatter what pinstate any of the input pins have, the motor just turns on uploading and even if i apply 5v to any of the pins, it just keeps turning the same direction.

Following the code. I hope someone could tell me what i am doing wrong, i am a newbie to programming:

int PUL=7; //define Pulse pin
int DIR=8; //define Direction pin
//int ENA=5; //define Enable Pin
int up = 2;
int down = 3;
int limitpin=1;
int limitpinup=4;
int i=0;

int buttonupstate = 0;
int buttondownstate = 0;
int limitstate=0;
int limitstateup=0;

void setup() {
  pinMode(PUL, OUTPUT);
  pinMode(DIR, OUTPUT);
  pinMode(up, INPUT);
  pinMode(down, INPUT);
  pinMode(limitpin, INPUT);
  pinMode(limitpinup, INPUT);
}

void loop() {
  buttonupstate = digitalRead(up);
  buttondownstate = digitalRead(down);
  limitstate = digitalRead(limitpin);
  limitstateup = digitalRead(limitpinup);
  i = 0;
  switch (limitstateup){
  case LOW:
    switch (limitstate){
    case LOW:
      if (buttondownstate==HIGH){
        do
        {
          digitalWrite(DIR,LOW);
          // digitalWrite(ENA,HIGH);
          digitalWrite(PUL,HIGH);
          delayMicroseconds(20);
          digitalWrite(PUL,LOW);
          delayMicroseconds(20);

          buttondownstate = 0;
          buttondownstate = digitalRead(down);
          limitstate == 0;
          limitstate = digitalRead(limitpin);
          limitstateup == 0;
          limitstateup = digitalRead(limitpinup);
        } while (buttondownstate == HIGH && limitstate == 0 && limitstateup == 0);
      }
      if (buttonupstate == HIGH){
        do
        {
          digitalWrite(DIR,HIGH);
          // digitalWrite(ENA,HIGH);
          digitalWrite(PUL,HIGH);
          delayMicroseconds(20);
          digitalWrite(PUL,LOW);
          delayMicroseconds(20);

          buttonupstate = 0;
          buttonupstate = digitalRead(up);
          limitstate == 0;
          limitstate = digitalRead(limitpin);
          limitstateup == 0;
          limitstateup = digitalRead(limitpinup);
        } while (buttonupstate == HIGH && limitstate == 0 && limitstateup == 0);
      }
      break;
    case HIGH:
      do{
        digitalWrite(DIR,HIGH);
        digitalWrite(PUL,HIGH);
        delayMicroseconds(20);
        digitalWrite(PUL,LOW);
        delayMicroseconds(20);
        limitstate = 0;
        limitstate = digitalRead(limitpin);
      }while (limitstate == HIGH );
      break;
    }
    break;
  case HIGH:
    do{
      digitalWrite(DIR,LOW);
      digitalWrite(PUL,HIGH);
      delayMicroseconds(20);
      digitalWrite(PUL,LOW);
      delayMicroseconds(20);
      limitstateup = 0;
      limitstateup = digitalRead(limitpinup);
    }while (limitstateup == HIGH );
    break;
  }
}

Thanks all of you,

Indeed there is nothing wrong with my code. The problem is indeed in the pull-down resistors, I rebuild the connection on a breadboard and works perfectly. I will have to check my PCB that contains all relays and resistors, the problem has to be on that board, bad connection or something like that.

However I would like to state that on the Osoyoo Uno board, the whole thing worked perfectly, so there has to be something different between Osoyoo Uno board and another Arduino board.

Here is the schematic to my PCB board. I checked it again, but i think all the digital pins have actually pull-down resistors active.


Liquid Crystal LCD Display Prints f in all rows and columns The problem is that the Liquid Crystal LCD display only prints "f" on every row and every column.

When I tell it to print something, then the display prints "f" on every square(row, column) for a brief second, then each square shows three white bars stacked up parallel to each other (quite like an "=" sign except that there's one more bar on top").

I am also using a tmrpcm library, so I'm guessing that interrupts might have to do with this, but I have no idea how to solve the problem.

The link to the tmrpcm library is as follows: https://github.com/TMRh20/TMRpcm

Thank you so much. I need to get this done by tomorrow 8 A.M., so I'm pretty desperate.

#include <LiquidCrystal.h>
#include <SD.h>                      // need to include the SD library
//#define SD_ChipSelectPin 53  //example uses hardware SS pin 53 on Mega2560
#define SD_ChipSelectPin 10  //using digital pin 4 on arduino nano 328
#include <TMRpcm.h>           //  also need to include this library...

TMRpcm tmrpcm;   // create an object for use in this sketch
char mychar;
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

volatile int pauseOnOff;

void setup(){

  tmrpcm.speakerPin = 9; //11 on Mega, 9 on Uno, Nano, etc

  if (!SD.begin(SD_ChipSelectPin)) {  // see if the card is present and can be initialized:
    Serial.println("SD fail");
    return;   // don't do anything more if not
  }
  else{
    Serial.println("success!");
  }

  tmrpcm.play("Closer.wav");

  lcd.begin(16, 2);

  lcd.print("hello, world!");
}

void loop(){

}

I don't know the source of the problem, but here are a few things that might help diagnose where the problem begins or what it is due to.

(a) To track execution progress, and detect which statement, if any, ruins LCD operation:  Create a routine to display current line number in code to LCD and Serial; make a macro ss to use for invoking that routine; invoke the macro before and after each line containing a tmrpcm action by calls like ss;.  See following example.

void shoLine(int line) {
  Serial.println(line);
  lcd.home ();     // Set cursor to 0,0
  lcd.print(line);
  lcd.print(' ');
  delay(200);  // /Delay long enough to see stuff appear
}
#define ss shoLine(__LINE__)

Note:  Move lcd.begin(16, 2); to be the first statement in setup() when using this method of debugging.

(b) If you find that the first few LCD calls are ok and then LCD output stops working, try turning off interrupts during LCD output.  That is, put a cli() or noInterrupts() call before an lcd.print(), and an sei() or interrupts() after it, and see if it then works.  If so, that might serve as a last-ditch workaround.  (I don't know whether LCD output routines use any interrupts; I doubt they do; but if they do, this method won't work.)

(c) If the LCD doesn't display correctly at all, even before the first tmrpcm action, it may be that the combination of tmrpcm with other code is using too much memory.  Carefully check the memory-usage reports when you compile your sketch.


Can anyone identify why this incrementer is losing count? I am working on a project where the end result is to count the number of cycles of a moving piece of metal using an inductive sensor.

For now I am using an Arduino Uno and have created a breadboard version for testing. The sensor has been replaced by a momentary push button. To check the count data I am viewing the number using Serial Monitor

All the elements of this set-up are working, apart from one major issue. When pressing the button the incrementer (++) occasionally adds 2 instead of 1 from only one button press. As a rough guide to the error frequency, it seems to count 11 for every 10 button presses. The error has never presented as not counting enough.

I am new to software, as such I cannot seem to see the error

Any help and guidance would be greatly appreciated

Here is the code I have written so far:

//Libraries
#include <EEPROM.h>

//Constants
const int counterPin = 2;   //Input from counter (looking for HIGH as external pulldown resistor is used)
const int EEPROMadress = 3; //holds the EEPROM address

//Variables
int counterState = 0;       //current button state
int counterStatePrv = 0;    //previous button state
int storedValue;
int presetCount = 100;

unsigned long countNumber;      //unsigned 32bit variable

void setup() {

    for (int i = 0; i < 255; i++) {
        // this performs as EEPROM.write(i, i)
        EEPROM.update(i, i);
    }
    for (int i = 0; i < 255; i++) {
        // write "presetCount" value to cell "EEPROMaddress" only the first time
        // will not write the cell the remaining 254 times
        EEPROM.update(EEPROMadress, presetCount);
    }

    pinMode(counterState, INPUT);
    Serial.begin(9600);

    countNumber = EEPROM.read(3);   //Start the counter at the presetCount value
}

void loop() {

    counterState = digitalRead(counterPin);   //Read the status of the counter input
    storedValue = EEPROM.read(EEPROMadress);

    if (counterState != counterStatePrv) {      //check that pulse went off
        if (counterState == HIGH) {             //check for pulse
            countNumber++;                      //increment (add 1) to the stored count value
            delay(10);
            Serial.print("Count  Value: ");
            Serial.println(countNumber);

            Serial.print("Stored Value: ");
            Serial.println(storedValue);
            Serial.println();

        }
    }
    counterStatePrv = counterState;

}

Buttons bounce (at least they appear to, electrically), meaning that if you're fast enough, you can detect multiple pulses per button-press. Usually we don't count the button as being pressed until we read the same value {n} times in a row or for {m} mSec, or some similar technique.

Because you call EEPROM.read() immediately after testing the button, perhaps most times the bouncing will have ceased when the call returns, but once in a while one last bounce slips through.

Nick Gammon, a regular contributer here, has a good discussion of de-bouncing on his web site. Have a look at that and pick a technique that's compatible with what you're trying to do.


How do I send a string to master using i2c I want to write an Arduino program that simply recieves a string (via the I2C wire library) from a master Arduino, then waits for a request, and sends that string back.

Here is my code:

#include <Wire.h>

void setup()
{
  Wire.begin(4);
  Wire.onReceive(receiveEvent);
  Wire.onRequest(requestEvent);
}

String data = "";

void loop()
{

}

void receiveEvent(int howMany)
{
  data = "";
  while( Wire.available()){
    data += (char)Wire.read();
  }
}

void requestEvent()
{
    Wire.write(data);
}

I read in the API that the write() function accepts a string, but I keep getting a "No matching function for call" error.  I tried to simply replace

Wire.write(data);

with

Wire.write("test");

and that worked without error.  Why is this the case?

data is a String. "test" is a char*. Wire.write() has no prototype that takes a String.

Wire.write(data.c_str());


Using GPS Module ET314AC With arduino Mega Can I use GPS Module ET314AC with Arduino Mega? Here is the datasheet of ET314AC            ET314AC Datasheet

yes you can, the datasheet is saying that you can read from a serial port which is what you want to do.

Connecting the serial port to TX and RX pins of the Arduino, ground and power, you should be able to talk to the module.

I cant find a breakboard for this module so I suppose you are going to solder it or you can give us the link where you bought it.

I suggest you to try with TinyGPS library to decode the data, after you are sure that the module is talking to the Arduino correctly.


Creation of multiple power cells to be controlled by Arduino I'm fairly new to the Arduino world, but have a history of good working knowledge of computers and software (I'm a software engineer), but I've only had the opportunity so far to create a few simple successful play-around projects.

I've decided to embark on a fairly ambitious project to build my son a ride on battery powered car for Christmas and trying to put all the pieces together.

An integral part of this plan is to develop what I call a couple of 'Power cells', which is simply a battery enclosure that has:

Updated:

An input from the Arduino to control the motor speed/voltage.
An input from either the Arduino or forward reverse switch to control the direction of polarity (make motor spin forwards or backwards)
Has a output to power the motor: 20V, drawing about 1-1.5 Amps
Has a output to power the 9x 12V LED lights on it, about upto 50W total (the LED lights will be controlled by the Arduino outside of the power bank, seeing there are a few of them).

I've drawn up a schematic that works with the components I've bought to help put the system together and was wondering if I am missing anything, critical or not?

Info about the battery I'm using can be found here: Aldi Xfinity 20V Li-Ion Battery teardown.

More Specifically:

Are there any errors with the cabling, I'm assuming no additional earth is required in a DC Circuit.
What size cables will i need to adequately service my power requirements?
Would I be able to control the reverse polarity switch directly from the Arduino? As I would like to also trigger a beeper when it is switched in reverse mode. Keep in mind the arduino would need to control 2-4 power cells.
I assume the controlling the potentiometer from the arduino I would need to use junction boxes between the arduino and the power cells to distribute the signal across each power cell, would this be the best way to do this?
The Li-Ion Battery also seems to have T output pin, i assume this is temperature monitoring, is there a way to utilize this input into the arduino for safety monitoring?
I was thinking of splitting the lighting power load between 2 power banks, would this be recommended / possible? (left power cell would power left side leds and right power bank would power right cell leds, with the exception of them both powering the center led).
Are there any additional safety precautions I should be following, especially working with a Li-Ion battery, ie. Fuse etc ?

I'm planning to make 2x of these Power cells to put in the car (each powers its own motor) (with the ability to add another 2 down the track).

Would really appreciate your feedback (please let me know if this is not the right place to ask this sort of question).

OK. Looks much better now. And I see one problem. It seems that the normal way to do the speed control is with a pot. A variable voltage at the input depending on the rotation. The Arduino low end designs have an analog out capability but it really is not analog. It is a pulse width variable signal that produces an on percentage between 0 volts and the CPU positive supply voltage. The boards do not have a real digital to analog converter. (maybe some higher end boards but not boards based on the Uno CPU.

It may still work but you need to integrate the pulse output and produce a real analog output voltage. A resistor on the output connected to a capacitor to ground will do the integration and filter out the pulses.

See http://www.ontrak.net/pwm.htm for more details.

The problem you might encounter is to much loading on the capacitor by the pot input circuit. Without more details about the module I couldn't say. The signal can be buffered with an amplifier but that adds to the complexity. Still would be doable though.

Or you can add a real digital to analog converter to the Arduino board. That would be my preference rather than having to add a buffer amplifier if a simple RC circuit wasn't good enough.

Do you have a link for that board?

From the picture of the linked speed module. It uses a LM324 opamp to generate the PWM signal. I did a quick look and found a typical circuit.

http://www.pcsilencioso.com/cpemma/graphics/erg_pwm_sch.gif

Typical but not the exact one. It is much as I expected. And if you did the RC only filtering then it may just work. The opamp input would not be too much loading on the capacitor. The concern that I have is that the 5 volt maximum from the Arduino may not be high enough to turn the motor on at its maximum value.


Arduino + Solenoid Lock I was trying to use a solenoid lock alongside the arduino, using a 12V 2A DC adapter, TIP120, and a diode.

The circuit looks something like this. However, the lock isn't going in automatically (it requires a push).

I've tested the circuit using a multimeter, and the output given by the transistor, is indeed 12V, however, when connected to the lock, the potential difference is around 8V. I don't know if that's normal, but the lock isn't going in on it's own.

Can anyone help me with this issue?

It sounds like your 12 volt adaptor is not powerful enough to operate the lock solenoid. If you power up the solenoid only and directly using the adaptor it should work. If it doesn't, you'll need a more powerful adaptor. If it does work, then the problem is somewhere in your driver circuit or Arduino sketch.


Peer to peer communication Hello guys ,
             I want to perform a mesh network between 3-4 modules using ESP8266 . Any one have idea how to do it?

You can't, that's not how the esp8266 works.

The esp8266 is WiFi, so you will either need an access point or nominate one esp8266 module to act as an access point running in softap mode.


Voltage measure range of an arduino? I recently thought of using an Arduino to measure voltage and I stumbled across the problem that what is the max voltage I can measure??? It is an Arduino Uno and I am thinking that I would also display the voltage measured on a 16 * 2 LCD screen.My guess is max of 5 volts but if this is correct how can I increase its range?

Without any further configuration, the ADC (Analog Digital Converter) of the Atmega328P (which is build onto the Arduino Uno) uses Vcc as voltage reference (meaning 5V in the case of the Arduino Uno). A voltage of 5V will result in the maximal value (which is 1023, since this is a 10bit ADC). So the voltage range in this case is 0 to 5V.

The Arduino Uno has an extra pin, where you can supply an own reference voltage. But it's limit is tied to the ADCs supply voltage AVcc, which is 5V for the Arduino Uno rev3 (as shown in the schematics of the Uno). The reference voltage should then be in the range of 1V to AVcc. So this still gives you only a range of 0V to 5V or smaller.

When you use a standalone Atmega328P, you can make AVcc a bit higher than the chips supply voltage Vcc, but at maximum Vcc + 0.3V.

You can check all these numbers by looking into the datasheet of the Atmega328P, chapter 28.9 (Electrical Characteristics --> ADC Characteristics).

How to increase this range depends greatly on your requirements. If you simply need a constant higher range, you can simply put a voltage divider in front of the analog input. Or you can use a more complex circuit involving an op-amp (amplifier ciruit, here with amplification factor below 1). You can even build this to be variable.

Should it be, that your wanted voltage range exceeds the 5V greatly, for example, if you want to measure mains voltage (230V for most europe, 110V in USA), you should definitely take great care and never connect this directly to electronic like the Arduino. High voltages (especially at high possible currents) should always be handled with great care.


How to send data from firebase php to arduino? In the project I am working on

  I want to send data to firebase going to arduino this specifically by
  sending an information to change the wifi

SSID

password

  materials I used:

esp8266-01

arduino uno r3

firebase

web server (000webhost)

  code for arduino

    #include <SoftwareSerial.h>
#include <DHT.h>;
SoftwareSerial Serial1(10, 11);
#define Trash "Trash3"
#define DHTTYPE DHT11
#define DHTPIN 2
#define TRIGGER_PIN 4
#define ECHO_PIN 3

DHT dht(DHTPIN, DHTTYPE, 11);

float humidity, temp_f;
int distance;
long duration;

String buff(64);
String getStr(128);

void setup() {

  Serial.begin(9600);

  Serial1.begin(9600);
  //Serial1.resetESP();
  delay(2000);
  Serial1.setTimeout(5000);

  dht.begin();
  pinMode(TRIGGER_PIN, OUTPUT);
  pinMode(ECHO_PIN, INPUT);

  if (!connectWiFi()) {
    Serial.println("Can not connect to the WiFi.");
    while (true)
      ; // do nothing
  }
  Serial.println("OK, Connected to WiFi.");

  sendCommand("AT+CIPSTA?");
  //sendCommand("AT+CIPDNS_CUR?");
  sendCommand("AT+CIPSTAMAC?");

}

void loop() {

  temp_f = dht.readTemperature();
  humidity = dht.readHumidity();
  digitalWrite(TRIGGER_PIN, LOW);
  delayMicroseconds(2);
  digitalWrite(TRIGGER_PIN, HIGH);
  delayMicroseconds(10);
  digitalWrite(TRIGGER_PIN, LOW);

  duration = pulseIn(ECHO_PIN, HIGH);
  distance = duration * 0.034 / 2;

  // connect to server
  if (sendCommand("AT+CIPSTART=\"TCP\",\"gg.com\",80")) {
    Serial.println("connected to Cloud");

    // build HTTP request
    getStr = "GET /upload.php?trash=";
    getStr += Trash;
    getStr += "&distance=";
    getStr += distance;
    getStr += "&temp_f=";
    getStr += temp_f;
    getStr += "&humidity=";
    getStr += humidity;
    getStr += " HTTP/1.1\r\n";
    getStr += "Host: gg.com\r\n\r\n";

    // open send buffer
    buff = "AT+CIPSEND=";
    buff += getStr.length();
    if (sendCommand(buff.c_str()) && Serial1.find(">")) { // AT firmware is ready to accept data

      // send HTTP request
      Serial.println(getStr);
      Serial1.print(getStr);

      // print HTTP response
      if (Serial1.find("+IPD,")) { // response received
        int l = Serial1.parseInt();
        while (l > 0) {
          if (Serial1.available()) {
            Serial.write(Serial1.read());
            l--;
          }
        }
        Serial.println("--------------");
      } else {
        Serial.println("no response");
      }
    } else {
      Serial.println("send error");
    }
    sendCommand("AT+CIPCLOSE");
  } else {
    Serial.println("Error connecting");
  }
}

bool connectWiFi() {

  if (!sendCommand("ATE0")) // echo off
    return false;
  if (!sendCommand("AT+CIPMUX=0")) // set single connection mode
    return false;
  if (!sendCommand("AT+CWMODE=1")) // set STA mode
    return false;
  return sendCommand("AT+CWJAP=\"CAPSTONE\",\"capstonemis\"");
}

bool sendCommand(const char* cmd) {
  Serial.println(cmd);
  Serial1.println(cmd);
  while (true) {
    buff = Serial1.readStringUntil('\n');
    buff.trim();
    if (buff.length() > 0) {
      Serial.println(buff);
      if (buff == "OK" || buff == "SEND OK" || buff == "ALREADY CONNECTED")
        return true;
      if (buff == "ERROR" || buff == "FAIL" || buff == "SEND FAIL")
        return false;
    }
  }
}

  code for firebase

<?php

require 'firebaseLib.php';
$Trash = $_GET["trash"];

$Distance = $_GET["distance"];
$Temperature = $_GET["temp_f"];
$Humidity= $_GET["humidity"];

// --- This is your Firebase URL
$baseURI = 'https://thesis1-69.firebaseio.com';
// --- Use your token from Firebase here
$token = 'gg';
// --- Here is your parameter from the http GET

$devicestatus= array('Distance' => $Distance,'Temperature' => $Temperature,'Humidity' => $Humidity);

$firebasePath = '/thesis1-69/';

$full= array($Trash => $devicestatus);

/// --- Making calls
$fb = new Firebase($baseURI, $token);
$fb -> update($firebasePath, $full);

?>

any  guide and help can help me a lot
thank you so much :)

add global variable String data; and in loop()

data = "trash=";
data += Trash;
data += "&distance=";
data += distance;
data += "&temp_f=";
data += temp_f;
data += "&humidity=";
data += humidity;

// build HTTP request
getStr = "POST /upload.php HTTP/1.1\r\n";
getStr += "Content-type: application/x-www-form-urlencoded\r\n";
getStr += "Content-length: ";
getStr += data.length();
getStr += "\r\nHost: gg.com\r\n\r\n";
getStr += data;


How Programing the nodeMCU Through OTA using GPRS? How Programming the nodeMCU Through OTA using GPRS?

Hi Everyone I need big help.

Actually, I m using NodemCU one of my project. the setup in Remote location, that place dont have a wifi option so I m using GPRS (GSM SIM800V)
for sensor data collection to my server. right now I need to update my new firmware to that NodeMCU.

is it possible do a OTA using GPRS (GSM SIM800V)?

plz help for this.

Thanks in advance.

Yes, it is possible, but it takes some work on your part.

I recently had to implement OTA updates for the ESP32 over an RS-485 link, and it's actually pretty simple to manage. The hard part (for you) is the communication connection.

Performing an update (assuming the flash is already partitioned and set up right for OTA updates) is a case of "starting" the update, passing the update manager the flash data, then "ending" the update:

Update.begin(size) - This starts the upgrade process. You need to provide the expected size of the flash data at this point.
Update.write(*data, length) - Pass a block of flash data to the updater for writing.  An alternative is to read directly from a Stream class, which will try and read the number of bytes specified in the size parameter to begin.
Update.end() - This will finish it all off and switch the bootloader to load from the new flash. If it worked fine it will return true, otherwise, it will return false.

Assuming the above worked, you can no reset the board with ESP.restart()

For added security you can also pass an MD5 hash of the data to Update.setMD5(md5) and the updater will check that the uploaded data matches that MD5 hash.

Of course, all this needs implementing in your program that is running on the target device before you try and do any OTA updates. And, of course, you need to arrange the actual upgrade channel to get the commands and data through to the target in the first place.

So:

Implement a method of getting the data to the target
Implement the updater code
Go to the device and upgrade the firmware
From that point on you should be able to use OTA updates through your own chosen mechanism.


Can I switch from Serial to SoftwareSerial at runtime with the same baud? I'm trying to use a GPS and the Adafruit thermal printer module with an Arduino Nano in the same project (both use baud 9600) and was wondering if I could do something like in the code below? Basically, in the example I made, I'm getting the time from the GPS and when it's on the minute, it will call the printTime() method.

What I'm wondering is if it's okay to do what I did in my disableGPS, enablePrinter methods by ending the serial connection for GPS and starting it for my printer? I feel like this should work, but I don't fully understand serial connections.

If this doesn't work, is there an alternative I could do? I never need to read from GPS and write to the printer at the same time in code.

#include <Adafruit_Thermal.h>
#include <TinyGPS++.h>
#include <SoftwareSerial.h>
#define PrinterTXPin 6 // Arduino transmit  YELLOW WIRE  labeled RX on printer
#define PrinterRXPin 5 // Arduino receive   GREEN WIRE   labeled TX on printer

static const uint32_t baud = 9600;
//Printer
SoftwareSerial PrinterSerial(PrinterRXPin, PrinterTXPin);
Adafruit_Thermal printer(&PrinterSerial);
//we only want to print on the minute
boolean havePrinted = false;

//GPS
TinyGPSPlus gps;
TinyGPSDate lastDate;

void setup() {
  enableGPS();
}

void loop()
{
  if(gps.time.isValid() && checkDate(gps.time)){
    printTime(gps.time);
  }
}

boolean checkDate(TinyGPSTime theTime)
{
 if(theTime.second() == 0 && !havePrinted)
 {
    havePrinted = true;
    return true;
 }
 if(theTime.second() == 1){
    havePrinted = false;
 }
}

void printTime(TinyGPSTime theTime)
{
  //Disable since we can only have 1 serial connection per baud
  disableGPS();
  enablePrinter();

  printer.doubleHeightOn();
  printer.println(theTime.hour() + ":" + theTime.minute());
  printer.feed(1);

  disablePrinter();
  enableGPS();
}

void enablePrinter()
{

  PrinterSerial.begin();
  printer.begin();
  printer.wake();
}

void disablePrinter()
{
  printer.sleep();
  PrinterSerial.end();
}

void disableGPS()
{
  Serial.end();
}

void enableGPS()
{
  Serial.begin(baud);
}

I think you are missing what the baud rate is.  It is the speed at which the data is transmitted.   So the fact that your two devices are the same is not an issue.   It looks like from the code that your gps is connected to the hardware serial(pins 0,1 on uno) and the printer is on a software serial( pins 5,6)   If this is the case, there is no reason to turn off either of them, they can both work. In the case of using multiple SOFTWARE serial connections, only one can be 'listening' at any time, so you must switch between them. This is not the case in your code, as there is only one software serial connection.


Syncing/taking external clock for SPI on Arduino Due I have an Arduino Due with a SAM3X8E chip and am trying to read SPI data from an external source that is communicating in SPI. I was able to get data by identifying specific bytes that are identifiers but realized that the clock for my board is not synced with the source coming in. I print out the bytes in hexadecimal format (08 00 FF AB etc) and each message is 128 bytes long.

To be clear, the source is an SPI master that is sending out data on its own MOSI line, but I am currently treating my board as a master as well since I do not know how to do Slave mode on Due. I connect the Slaves MOSI line to my boards MISO line, and just transfer data and read 128 bytes but it would appear that I am not getting the same data. Is there a way for my to take in the clock from the external clock and synchronize my board with that clock to make sure? My source code is below. The only methods I can think of are to either figure out how to implement the board in slave mode (i'm not familiar enough with the registers and how to change this, or read data in slave mode) or synchronize the clocks so my board is reading and sampling the source data correctly.

Could someone check if my thinking is correct, or do I not need to make any changes since the data is in a shift register?

Thanks

void setup(){
Serial.begin(9600);
SPI.begin();
SPISettings settings (50000000, LSBFIRST, SPI_MODE1); //Sampling rate    50Mhz, source's max speed
SPI.beginTransaction(settings);
}

void loop(){
  int i = 0;
  uint8_t value;
  value = SPI.transfer(0x00);
  while (value != 8){//searching for identifier 0x08
    value = SPI.transfer(0x00);
  }
  SPI.transfer(buffer, 127);//get the rest of the 127 bytes
  Serial.print(value, HEX);
  Serial.print(" ");
  for (i = 0; i < 127; i++){
    if (buffer[i] == 0){
      Serial.print(buffer[i],HEX);
      Serial.print(0, HEX);
    }
    else{
      Serial.print(buffer[i], HEX);
    }
    Serial.print(" ");
  }
  Serial.println("\n");
}

For your external source to be an SPI bus master, it has to be the only one generating the clock signal. Yet, calling SPI.transfer() also generates a clock signal from the Arduino; both devices are attempting to drive the clock line simultaneously, hence your problems.

You have to bit-bang this or manipulate the SAM registers yourself to configure it as a slave; the SPI library doesn't support slave mode.
In order to bit-bang, you'll have to define your own MOSI, SCK, SS (and MISO, if you'll be writing to the master) pins and do all the sampling yourself with digitalRead(); there are no registers to be read from since you aren't using the SAM's SPI peripheral.

Since your SPI mode is MODE 1, it means the clock idle polarity is LOW, and that data is sampled on the falling edge. To bit-bang with digitalRead(), it is necessary that the SCK frequency be below 50 kHz (digitalRead() takes about 4us), taking overhead into account. You should use direct port manipulation, if you need a higher frequency. If you'll be blocking till you've read data, and assuming that the external source always sends data in byte units, then a basic algorithm:

Create a byte array to hold all the expected bytes
Define a byte variable (curr_byte, maybe) for holding each byte received
Wait till the SS pin goes LOW
Clear curr_byte to zero
Wait till SCK goes HIGH
Wait till SCK goes LOW
Read the bit on the MOSI line and shift it into curr_byte
If you've received up to 8 bits so far, save curr_byte to the byte array; if SS is still LOW, go to step 4, else exit this loop. But if you haven't received a complete byte yet, go to step 5.

After you leave the loop, you can then confirm the bytes you've received with Serial. If the external device can send data with any number of bits, then you should always check the SS line after you shift in a bit, to determine if the Due has been deselected or not i.e. if there are any more incoming bits.


Stacking Arduino Shield (Motor Shield, LCD Keypad, LED Sensor) I'm building a line follower with arduino, here some part that I'm going to use

Arduino Uno
Motor Shield 2A http://www.dfrobot.com/index.php?route=product/product&product_id=69
LCD Keypad
4 Channel Line Tracking Sensor http://www.aliexpress.com/item/4Channel-Infraed-Line-Tracking-Sensor-Module-w-Connector-Line/2021343637.html

I'm using LiPo Batteries 3 Cell 11.1v for power source.

I'm new in here so I didn't know how to stack that shield, if I recall I can stack up Arduino and the LCD Keypad, and Arduino and the Motor Shield, but didnt know how to stack those 2 together and adding another sensor like that line tracking sensor. May I know how to resolve that? thanks.

The Motor Shield 2A plugs in on top of the Arduino Uno, and the LCD Keypad plugs in on top of the motor shield. [But see Edit 1 below]

There is better information about the  4 Channel Line Tracking Sensor at uctronics.com where you can see that its main board (with the LM339 chip) connects to the Arduino via six lines: Vcc, Gnd, Out1, Out2, Out3, Out4.  That main sensor board does not mount on the stack, but instead can be located whereever is convenient and leaves its four comparator-level pots accessible for adjustment.
Mount the four small boards for the tracking module as convenient and necessary for line following.

For connecting the six lines from the sensor main board to the Uno, you probably will need to solder two headers (rows of pins) to a board in the stack.  Using right-angle headers (see below) will allow the pins to come out of the side of the stack without interfering with other layers of the stack.  One of the headers should let you connect sensor Out1...Out4 digital outputs to four otherwise unused analog or digital pins, and the other header should let you connect Vcc and Gnd.

Edit 1: In the LCD shield page, section 2 (Diagram) shows Vcc, Gnd, and D0-D3 available at the top right corner (the angled corner).  Those six pins probably are a reasonable place to add a six-pin angled header for the sensor board.

Given that the LCD KeyPad Shield is a DFRobot.com model, the summary pinout at shieldlist.org shows that its use of D4,5,6,7 will conflict with use of those same lines by the DFRobot 2A Motor Shield.  There are several ways to handle a conflict like this:  1, use two Uno's, one per shield; 2, make one shield or the other use different lines; 3, share the lines.

Method 2 could work as follows:  Stack the LCD shield directly on the Uno (or any other compatible Arduino).  Besides a header for the sensor board, add a header for a cable to the motor board, and drive the motor board's D4-7 inputs with some other lines from the Uno, eg A4-7.  [Alternately  one could remove the D4-7 pins on the LCD shield and jumper from A4-7 to the D4-7 lines on the LCD shield.  This would leave the boards in a single stack but would make some serious changes to the LCD board.]

Method 3 would work as follows:  The LCD shield only pays attention to D4-7 (which from the DFRobot schematic drive DB4-DB7 on an LCD TC1602 chip) when the TC1602's E line is strobed.  See pages 7 and 8 of Adafruit.com's copy of TC1602 specs, where timing diagrams show about half-microsecond times for writing to or reading from the TC1602.

You would need to run tests with your motors and see if they work ok in spite of the four inputs to the motor shield being random during the occasional half-microseconds that data is being written to the LCD.  You might have to add more diodes or capacitors to  suppress electrical noise due to rapid switching.

DFRobot's motor shield page has links to that board's schematic and to its L298 chip data sheet.  Page 7 of the datasheet says

  An external bridge of diodes are required when inductive loads are driven and when the inputs of the IC are chopped; Shottky diodes would be preferred.

The motor shield schematic shows diodes; although not drawn using Schottky diode symbols they might be Schottky anyway (which would give better noise suppression, less heating, etc).  The schematic also shows that JP1, a 16-pin dual row header, has jumpers that control ENA and ENB on the L298.  In a "proper solution" for sharing D4-7 between the LCD and motor shields, you'd drive ENA and ENB low when using D4-7 for LCD i/o, which would allow the attached motors to briefly free run, as opposed to being suddenly commanded to stop or reverse.


Read only selected Packet SoftwareSerial I am reading data from RS485 which is in the following format:

void sendkwh()
{
  RS485Serial.write((byte)0x01); // Meter Address
  RS485Serial.write((byte)0x03); // Read Function Code
  RS485Serial.write((byte)0x40); // Register Address Variable (Start address high bit)
  RS485Serial.write((byte)0x34); // Register Address Variable (Start address low bit)
  RS485Serial.write((byte)0x00); // Register Quantity (High Bit)
  RS485Serial.write((byte)0x02); // Register Quantity (Low Bit)
  RS485Serial.write((byte)0x90); // CRC check code (CRC code Low bit)
  RS485Serial.write((byte)0x05); // CRC check code (CRC code High bit)
}

and I need to read only the 4th and 5th frame of the packet. I am doing it the following way:

RS485Serial.listen();
  if (RS485Serial.available() > 0)
   {

    if(RS485Serial.read() == 0x01)
    {
    for(int i=0; i<4; i++) {

   byte discard = RS485Serial.read();

   }
    byteReceived = RS485Serial.read(); // 4th frame
    byteReceived2 = RS485Serial.read(); // 5th frame

which is working fine. I wanted to know if there is a method to discard the packets without loop?

As in I have changed the sendkwh() as below:

byte SendKWh[] = { 0x01, 0x03, 0x40, 0x34, 0x00, 0x02, 0x90, 0x05 };
RS485Serial.write(SendKWh, sizeof(SendKWh));

But don't know how to proceed with tapping the 4th and the 5th frame. Your help is appreciated.

Your reading methodology is flawed from the start and you need to completely change how you do things.  First off, you wait until there is at least one byte in the incoming buffer, then if that byte is 0x01 you then try and read 5 more bytes - even if there is only (say) 2 bytes in the buffer.

Instead you need to set up a sliding window for receiving the data. A sliding window is basically an array that is the same size as the data you are receiving, and as bytes become available they work their way down from the "top" to the "bottom" of the array. When the contents of the array match a certain pattern you know it is a "good" packet and you can use the data form it.

For example, you may have something like:

uint8_t window[8];

void loop() {
    if (RS485Serial.available()) {
        uint8_t b = RS485Serial.read();
        // Slide the contents of the array down
        for (uint8_t i = 0; i < 7; i++) {
            window[i] = window[i+1];
        }
        // Insert at the top
        window[7] = b;

        // If the array starts with 0x01,0x03,0x40,0x34...
        if ((window[0] == 0x01) && (window[1] == 0x03) &&
            (window[2] == 0x40) && (window[3] == 0x34)) {
            // Do something with window[4] and window[5]
        }
    }
}

You could also add checking the CRC to that by comparing the calculated CRC for the incoming packet (however that is done in this protocol) with the last two bytes of the array.


NTP Client Library. Set sync provider pointing to public class function. Possible? I am trying to develop a NTP client library for ESP8266/Arduino to make adding NTP sync an easier task.

Basically, I've thought about a constructor as NTPClient(String host, int interval); and a NTPClient.begin() function to register sync function.

My problem is with that registering.

I have a public function: time_t ntpClient::getNtpTime() that connects to NTP server, decodes the response and returns a time_t variable.

Then, inside boolean ntpClient::begin() function I try to run setSyncProvider(ntpClient::getNtpTime). I've also tried to use setSyncProvider(this->getNtpTime).

I get a compile error here:

ntpClient.cpp:In member function 'boolean ntpClient::begin()
ntpClient.cpp:79:39: error: cannot convert 'ntpClient::getNtpTime' from type 'time_t (ntpClient::)() {aka long int (ntpClient::)()}' to type 'getExternalTime {aka long int (*)()}
  setSyncProvider(ntpClient*:getNtpTime)
Error compiling project sources

What could I do to allow registering this function as sync provider to hide NTP internals to my sketches?

What could I do to allow registering this function as sync provider to hide NTP internals to my sketches?

The function should be a static member function. A "normal" member function does not have the right prototype as there is a hidden parameter ("this").

static time_t getNtpTime();

To solve this you need a single-ton (an instance of the client class) that the static function can use.

class NTPClient {
public:
   NTPClient() ...
   {
     ...
     s_client = this;
   }
   time_t getNtpTime();
   ...
   static time_t getNtpTime() ( return (s_client->getNtpTime()); }
   ...
protected:
   static NTPClient* s_client;
   ...
};
...
NTPClient::s_client = NULL;
...
NTPClient ntpClient;
...
setSyncProvider(NTPClient::getNtpTime)

Alternatively a global function and a known instance:

class NTPClient { ... };
extern NTPClient ntpClient;
...
time_t getNtpTime() { return (ntpClient.getNtpTime()); }
...
setSyncProvider(getNtpTime)

Cheers!


Compiling Error - exit status 1 for DHT11 using Arduino UNO (code/process/connections same as website given bellow) https://create.arduino.cc/projecthub/MisterBotBreak/how-to-use-temperature-and-humidity-dht-sensors-9e5975
Copied Error Message:
Arduino: 1.8.13 (Windows 10), Board: "Arduino Uno"

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

C:\Users\soumy\OneDrive\Documents\Arduino\libraries\DHT-sensor-library-master\DHT_U.h:36:10: fatal error: Adafruit_Sensor.h: No such file or directory

 #include <Adafruit_Sensor.h>

          ^~~~~~~~~~~~~~~~~~~

compilation terminated.

exit status 1

Error compiling for board Arduino Uno.

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

The code:
#define DHTPIN 2
#define DHTTYPE DHT11

DHT dht(DHTPIN, DHTTYPE);

void setup() {
  Serial.begin(9600);
  Serial.println("DHTxx test!");

  dht.begin();
}

void loop() {

  delay(2000);
  float h = dht.readHumidity();
  float t = dht.readTemperature();
  float f = dht.readTemperature(true);

  if (isnan(h) || isnan(t) || isnan(f)) {
    Serial.println("Failed to read from DHT sensor!");
    return;
  }

  float hif = dht.computeHeatIndex(f, h);
  float hic = dht.computeHeatIndex(t, h, false);

  Serial.print("Humidity: ");
  Serial.print(h);
  Serial.print(" %\t");
  Serial.print("Temperature: ");
  Serial.print(t);
  Serial.print(" *C ");
  Serial.print(f);
  Serial.print(" *F\t");
  Serial.print("Heat index: ");
  Serial.print(hic);
  Serial.print(" *C ");
  Serial.print(hif);
  Serial.println(" *F");
}

I didn't download the "Adafruit Sensor Library"
https://github.com/adafruit/Adafruit_Sensor
It ran after I added it.


using references to SFRs in gcc inline assembler I want to write a driver that can use either timer0 or timer2, based on a choice made at compile time.

So I want all references to timer registers to be abstracted, e.g. OCRA for OCR0A/OCR2A, etc.

I could do it with plain macros, like so:

#define _CONCAT3(a,b,c)   a##b##c
#define CONCAT3(a,b)   _CONCAT3(a,b,c)

// set timer number globally
#define MY_TIMER 2

// define an alias for each control register
#define OCRA CONCAT3(OCR, MY_TIMER, A)

but for some reason I don't want to use macros there.

So I came up with this scheme:

typedef volatile uint8_t& tRegister;

constexpr volatile uint8_t& timer_register (volatile uint8_t& a, volatile uint8_t& b)
{ return MY_TIMER==0 ? a : b; }

tRegister OCRA = timer_register (OCR0A, OCR2A);

It works pretty well for all its awkwardness, but when I try to use this definition in an inline assembly directive, I get strange results:

asm volatile("lds r24, %0" : : "i"(&OCRA));

will get an error: impossible constraint in 'asm'

Now this:

asm volatile("lds r24, %0" : : "i"(&timer_register (OCR0A , OCR2A )));

will compile (and produce lds r24, 0x00B3 as it should).

By definition a reference to a static variable is a constant address, known at compile time, so I can't see why it can't be used in this context.

So my questions are:

what is going on there?
how to alias these registers (without macros) to please the inline assembler?

You could use pointers instead of references. With pointers, you have
the separate notions of “constant pointer” and “pointer to constant”. A
reference is a kind of pointer coated with syntactic sugar. However,
whereas you can have a “constant reference” (equivalent to pointer to
constant), I do not know how to declare a “reference with constant
address” (which would be the equivalent of a constant pointer). And
this is your issue: the "i" constraint in the asm statement requires
a constant.

Here is my take with pointers:

typedef volatile uint8_t * tRegister;

constexpr tRegister timer_register(tRegister a, tRegister b)
{ return MY_TIMER==0 ? a : b; }

// The `const' below is essential.
const tRegister OCRA = timer_register(&OCR0A, &OCR2A);

asm volatile("lds r24, %0" : : "i"(OCRA));

Of course, you then have to change all your OCRA = ...; statements
with *OCRA = ...;, which is awkward. But note that the avr-libc
defines the SFRs with macros equivalent to

#define OCR0A (*address_of_OCR0A)

If you want this convenience, you may have to resort to using similar
macros yourself.


In UART, what mechanism sets the "new data received" flag back to 0? I was reading documentation on UART on AVR and it looks simple: when a flag (bit RXC0 of register UCSR0A) is set to 1, it means the micro controller has new data for you, and you read this from register UDR0.

But something boggles my mind: How does the micro controller know that we have read the data? Or, in other words, after it received the first byte on UART, the flag is set to 1, but when is it set back to 0?

The ATmega328p data-sheet describes the setting of RXCn:
Bit 7 – RXCn: USART Receive Complete

This flag bit is set when there are unread data in the receive buffer and cleared when the receive buffer is empty (i.e., does not contain any unread data). If the Receiver is disabled, the receive buffer will be flushed and consequently the RXCn bit will become zero. The RXCn Flag can be used to generate a Receive Complete interrupt (see description of the RXCIEn bit).

The hardware seems to keep a register the size of the receive buffer. Incremented when received and decremented when read. It is only one level so the size is 0..1, i.e. one bit.
Actually there is two registers; one for possible incoming data and one for the latest data until read.
Cheers!
More details in ATmega328p data-sheet, chap. 19 USART0


Using map for DC motor instead of servo I am trying to use map command which is used to power servo 180 degrees as the potentiometer moves...

in fact what i want to do is just when i adjust my potentiometer to zero; stop the dc motor then after turn the pot to 512 analog value turn the motor to the left (digitalWrite(I1, HIGH); digitalWrite(I2, LOW);)and then stop when it reach 512 then when adjust the pot back to zero turn the dc motor to the right (digitalWrite(I1, HIGH); digitalWrite(I2, LOW);) but the think is what i am trying to do is exactly what we can do with the servo motor in the knob http://www.arduino.cc/en/Tutorial/Knob

I'm using a normal DC motor and l293D IC but I want to control the DC as knob method like the 200 degrees.

Code

#define E1 11    // Enable Pin for motor
#define I1 10    // Control pin a for motor
#define I2 9     // Control pin b for motor
const int analogPin = A0;
int analogValue ;

void setup() {
  pinMode(E1, OUTPUT);
  pinMode(I1, OUTPUT);
  pinMode(I2, OUTPUT);

}

void loop() {

  int analogValue = analogRead(analogPin);

  if(analogValue > 0 && analogValue < 512)  {

  analogWrite(E1, 255);
  digitalWrite(I1, HIGH);
  digitalWrite(I2, LOW);
    delay(100);
} else
  analogWrite(E1, 255);
  digitalWrite(I1, LOW);
  digitalWrite(I2, HIGH);
 }

It looks like you want to use the "analogValue" to control the direction and speed of your DC motor.  If this is correct consider using this:

      //This method assumes: The center position of the pot is the motor's 0 speed point,
      //(because this is an ideal speed to actually reverse the motor's direction).
      //A PWM control range of 0-255, and the ADC input range of 0-1023.

      //First create a relative speed value from "analogValue",
      //with the pot mid point at 0 speed, and pot high/low points being full speed.

      int motorSpeed = 0;
      if (analogValue < 512 )
      {
       motorSpeed = map(analogValue, 0, 511, 255, 0);
      }  //Note that mapped range is reversed to give 0 speed at mid point.
      else
      {
       motorSpeed = map(analogValue, 512, 1023, 0, 255);
      }

      //then replace each analogWrite(E1, 255) with:
      analogWrite(E1, speedValue);

      //you should also change "  if (analogValue > 2 && analogValue < 500) {  " to:
      if (analogValue < 512) {


Can I use my Arduino nano to upload sketch in Uno's ATmega328p chip? I can not upload sketch to my UNO directly. My ATmega16U2 doesn't work.But the Atmega328P processor still work.
 I have an arduino nano lying around. Can I use it to upload sketches to Atmega328P directly.
Thanks in advance

Yes. You can. Either as a USB to UART adaptor and use the Uno's bootloader as you would with any bootloader-enabled breadboard Arduino, or as an Arduino ISP to program the chip directly through the ICSP pins as you would when putting the bootloader onto a blank chip.


What requirements should components have to work with Arduino (UNO in particular) I am fairly new to the whole concept of Arduino and electronic engineering in general.

Recently I bought myself an Arduino UNO and I'm wondering what "non off the shelf" components will work when I hook them up with the UNO. I have a lot  of old electronic stuff laying around containing pushbuttons, sliders, faders, knobs etc. wich if possible, I'd like to take apart to connect them to the UNO for some fun fuzzin' around.

Many thanks in advance!

PS: this is my fist post ever on stackexchange so excuse me if the question is placed incorrectly or the tags are weird. Please DO correct me where I'm wrong.

When it comes to electronics, hypothetically anything can be connected to anything else. The only real barriers are time, cost, and practicality.

Two major things to look out for though are voltage and current requirements.

Most Arduinos operate at 5 volts, so it's often easiest to connect it to other electronic devices which also operate at 5 volts. That certainly doesn't mean you can't connect an Arduino to something that operates at 3.3 volts (for example). However, it means you may need to add some voltage level conversion circuitry (although it's not always necessary, depending on the context).

Regarding current, a critical issue to look out for is how much current something will draw. For example, a motor will often require more current than an Arduino can safely provide. That means you'd need some kind of external power supply which can be switched by the Arduino.

The most valuable thing to do is to learn to find and read datasheets. These give information about electronic components, specifying things like voltage, current, timing and so on. For situations where there's no datasheet available, you may find it useful to learn how to use a multimeter and an oscilloscope to monitor how equipment behaves.


Any way to use F macro with a passed variable? I want to know if it's possible to use the F() macro on text that is being passed to a function.

This is an example function:

void displayMenu(const char * txt, byte &var) {
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print(txt);
  lcd.setCursor(0, 1);
  lcd.print(var);
}

This is how I'm calling the function:

displayMenu("Backlight:", backlight);

If I didn't separate the repeating code into a separate function, I would've been able to write it out like this:

lcd.clear();
lcd.setCursor(0, 0);
lcd.print(F("Backlight: "));
lcd.setCursor(0, 1);
lcd.print(var);

If I try to do:

displayMenu(F("Backlight"), backlight);

it doesn't work. Also if I try to do this in the function:

lcd.print(F(txt));

that also doesn't work.

I'm just wondering if such a thing is possible.

There is a special type for just this occasion - the __FlashStringHelper type.

void displayMenu(const __FlashStringHelper *txt, byte var) {
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print(txt);
  lcd.setCursor(0, 1);
  lcd.print(var);
}

Note I removed the & from var - you don't want that unless you are passing a complex class or are wanting to modify the contents of var in the function and have it reflected back outside the function.  Passing a reference to a byte (&var) requires two bytes of data - just passing the content of a byte only requires one byte of data.


iterate through 8 thermocouple sensors (MAX31856) I have 8xMAX31856 and I am trying to use the Adafruit library. Instead of writing all 8 thermocouple channels each time in code (and wasting memory), I want to store the objects in an array and loop through them periodically.
Here is my code:
Adafruit_MAX31856 TCouple1 = Adafruit_MAX31856(2,11,12,13);
Adafruit_MAX31856 TCouple2 = Adafruit_MAX31856(3,11,12,13);
Adafruit_MAX31856 TCouple3 = Adafruit_MAX31856(4,11,12,13);
Adafruit_MAX31856 TCouple4 = Adafruit_MAX31856(5,11,12,13);
Adafruit_MAX31856 TCouple5 = Adafruit_MAX31856(6,11,12,13);
Adafruit_MAX31856 TCouple6 = Adafruit_MAX31856(7,11,12,13);
Adafruit_MAX31856 TCouple7 = Adafruit_MAX31856(8,11,12,13);
Adafruit_MAX31856 TCouple8 = Adafruit_MAX31856(9,11,12,13);

char* thermocouples[] = {TCouple1, TCouple2, TCouple3, TCouple4, TCouple5, TCouple6, TCouple7, TCouple8};

however, I am met with this error on compile:
cannot convert 'Adafruit_MAX31856' to 'char*' in initialization

Why can I not store these variables in an array and call on them later? Is there another way to do this? They work on SPI logic...

You CAN store them in an array, but NOT in an array of pointers to characters. That is just the wrong type. Try
Adafruit_MAX31856 thermocouples[] = {TCouple1, ...}

or even ditch the first declarations and use
Adafruit_MAX31856 thermocouples[] = {
    Adafruit_MAX31856(2,11,12,13),
    Adafruit_MAX31856(3,11,12,13),
    Adafruit_MAX31856(4,11,12,13),
    ...
};

I don't have that library installed, but I tried compiling this pattern with the Bounce2 library and it works. That looks like this:
Bounce buttons[] = {
    Bounce(),
    Bounce(),
    Bounce()
};


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:

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


What is the right way to query an I2C device from an interrupt service routine? The ADXL345, for example, requires that interrupts are responded to by querying the INT_SOURCE (interrupt source) register. In example code for the SparkFun ADXL345 Arduino Library, there is code that looks like:

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

  // Free Fall Detection
  if(adxl.triggered(interrupts, ADXL345_FREE_FALL)){

However, under the covers adxl.getInterruptSource() is sending an I2C message and receiving a response. This seems to be a bad idea in an interrupt service routine (ISR).

A possible option seems to be to turn on interrupts prior to calling adxl.getInterruptSource(), however there is much advice about not doing this (such as, Nick Gammon's informative post). I've managed to get it to work with something of the form:

void setup() {
  attachInterrupt(digitalPinToInterrupt(INT_PIN), isr, LOW);
  ...
}
void isr() {
  detachInterrupt(digitalPinToInterrupt(INT_PIN));
  interrupts();
  byte interrupts = adxl.getInterruptSource();
  ...
  attachInterrupt(digitalPinToInterrupt(INT_PIN), isr, LOW);
}

This seems to work but I'm worried I'm missing something. Any suggestions?

EDIT: Thanks for the answers that suggest polling, however I am using a MKR1400 and wish to minimise power consumption by putting the processor into a sleep state - only waking up to process the relatively rare "activity" or "free fall" events. As pointed out by @Majenko, a combination of sleeping and polling might be used. So this really just leaves the question of why is the above a bad idea.

Just because a pin is called "interrupt" doesn't mean that you have to read it using an interrupt input.  The INTx pins of the ADXL345 are simple "level" outputs.  All the time there is an "interrupt" pending (a signal from the ADXL345 that something has happened) the corresponding INT pin is held LOW.  It remains LOW until the interrupt has been handled by your code.

It's not something that is very brief - it's something that persists as long as you need it to.

You can just read the INTx pins with normal digitalRead() from within your loop() function (polling). Unless you really need to respond right now to an event on the ADXL345 there is no need to use an interrupt input.


I need 70 or more input pins for the Arduino -how to do this? I have some SN74HC165N, CD4021B chips. How many (minimally) such ICs would I need to get 70 inputs to an Arduino Uno? What is the exact circuit diagram and the code? Im not sure how the wring cascades into each of the chips to make it grow to over 70 inputs, or what the code is for the 70 input circuit. I do understand how to use one of those ICs though. My second easier question is -is there an development board with 70 or more inputs?

CD4021B,SN74HC165N are the chips, you know the ones, that has a parallel input pins that are listened to by latch pin, and the clock pins such outputs the parallel data into the serial data-so I am interested with solution with this pin because I know how it works.

It is for sure 70 pins that are required -not any less-I am sure of that. Because the inputs cannot be further simplified to less than 70. The reason the inputs are 70 is because the algorithm used has 70 free variables in it. Hence by definition it uses 70 or more variables. The input for each of the 70 inputs can be a digital high or a digital low but this is not known before hand. So it cant be simplified because it like saying you can simplfy the information from 70 or more sensors at runtime, and each sensor has an unpredictable value. Anyway this explanation is moving away from the point of my question. I just want to know the circuit that does 70 inputs or more using the mentioned IC-I can live with that answer even if its not the most efficient.

The best way I know to do it is by using the MCP23017, which gives you 16 extra GPIOs via I²C communication. They can be configured for both input and/or output. I've done it myself and it worked like a charm. It has 3 pins for dynamic addressing (3 bits), which allows you to use up to 8 (0..7) MCP23017 for a total of 128 extra GPIOs.
This is the chip datasheet:
(http://ww1.microchip.com/downloads/en/DeviceDoc/21952b.pdf)
There's a lot of examples about its use on the internet. Just google for "MCP23017 arduino" and you'll find them. For example:
http://tronixstuff.com/2011/08/26/tutorial-maximising-your-arduinos-io-ports/


Arduino Uno + Ardumoto + BT robot works from USB but not from baterries My Arduino UNO board is part of a small robot that works when connected to the laptop by USB but it does not when plugged to the batteries. The baterries plug seems okay, it outputs 7.8 V. My UNO is connected to an ArduMoto board that manages the robot motors as well as a bluetooth chip. I have little experience with Arduino or electronics in general so I am stuck on the best course of action.

1) Can I find out what is wrong with the power supply without completely isolating UNO from the robot?

2) If I separate UNO, how can I find out with certainty if my UNO power supply is damaged or not? Is there something in particular that I could measure with my multimeter?

UPDATE

After fully charging my batteries I observed that the LEDs attached to the motor outputs are blinking fast. They blink for about one minute then nothing happens anymore. On USB everything works as expected. Those LEDs show that signal is going towards the motors, but why is it so different to USB? On USB power, the LEDs blink only when I command the robot to move through the BT board while under baterries they blink furiously for a minute and that is all that happens.

I also don't know what happened to the batteries, they seem to be fully drained in just one minute, but I don't know how to test that, they appear to still have high voltage.

I use two LC 18650 4800 mAh 3.7 V UltraFire baterries. The motor shield is Ardumoto Keyes_L298P, very similar to Sparkfun's Ardumoto shield.

I do not have the actual code that is on my Arduino. It must be similar to the code on this page, since I am using their Android app for BT communication with my robot, and it works on USB power supply.

Are you powering the motors with a separate supply, and not direct from the Arduino? Motors should be powered separately and the power only switched by the Arduino. Otherwise, their current draw could be pulling down your battery voltage. And even with USB power, they could be drawing more current than spec'd for either the USB power source or the Arduino's regulator or output pins. The chip itself is spec'd for a maximum current of 40mA per pin and 200mA total.


Blink question with breadboard & LED I tried a basic Blink example and I found a strange case where :

Works

Does not work

Can someone explain me what is happening ?

It is because the rail in the middle breaks the vertical connections.
So the positive leg in the first example is not connected to the negative leg of the LED.

In your second example both the negative leg and the positive leg are connected on the same rail, because of the that the power is not flowing through the LED but directly back to the GND pin of your arduino.

Same for the resistor. Since both legs are connected to the same rail, the resistor has no effect.


Amplified piezo sensor wiring problem I am trying to amplify the signal from an Adafruit Small enclosed piezo.  The piezo is working using the Arduino Knock example but I want to increase the sensitivity using an amplifier.  The wiring shown below does not work using the Knock sketch and I am assuming it is a problem with the wetware and the wiring(NOOB here).
Any advice in amplifying the piezo is appreciated.

You don't seem to understand how to wire an OP-AMP. Here is a quick tutorial on their basics:

https://www.youtube.com/watch?v=kqCV-HGJc6A

The thing is that you are missing a LOT of resistors. An usual OP-AMP circuit contains many resistors to determine the amount of amplification and more...

The tutorial explains quite well what resistor and where do you need to put them in order for your circuit.