text:
How do I get status of contactors using Arduino (more than 50 contactors)
I am new to Arduino. Sorry if my question sounds wrong.
Interest areas: Multiple devices inter-connected on the cloud.
Single GSM for equipment in a typical panel connectivity for non-electrical parameter sensing devices e.g. Temperature, humidity.
Mechanical operations & connection status
Parameters of individual devices [non-communication capable]
Connectivity with cloud
Interest areas: Connectivity for electromechanical devices – Contactors, MCBs, RCCB etc
Parameters possible on IOT
Device Status possible on IOT
Size [Compactness] of the IOT solution to be integrated
Aux Power requirement & possible ways to provide the same
Memory retention
Remote access/control and driving of the devices
The estimated cost of the IoT connectivity devices should be a fraction of the device cost [e.g. Contactor of 9A].
Voltage level high
I am trying to read the status of more than 50 contactors i.e whether they are in ON\OFF\trip state using Arduino and display it on screen.
Can I use a single microcontroller to read the status of 50 or more contactors?
I searched on the net and I found out it can be done using shift registers or a latching system, but I didn't understand the method at all.
Please, can anyone explain me the method of doing this?Thanks.

Comments are not for extended discussion; this conversation has been moved to chat.

Due to lack of specifics, I cannot be more precise with my answer, but since you are working with "high" voltage (I'll assume 220V/415V) I would suggest the best solution to monitoring the current will be current transformers.
These are non-intrusive devices that you pass a single conductor through. It generates a small current in proportion to a large current flowing through the conductor.
This small current is then converted into a small voltage by passing it through a resistor and then measuring the voltage across that resistor.
Since it is AC you are dealing with simple digital IO pins will not suffice (except see below) - no matter how many you have. You need analog inputs, and you need to be able to sample that analog signal fast enough to at least capture the peaks and troughs of the incoming waveform. That means sampling at many times the frequency of the supply. For 50Hz you want to sample either at, say, 500 sps or more, or to sample at a rate that isn't a multiple of, or factor of, 50, but for a longer period of time.
Interfacing an AC voltage like this involves adding an offset voltage to it so that the zero point of the AC voltage lies in the middle of the ADC's range. This is most often done by feeding a voltage of 50% Vcc into the current transformer as a "virtual ground", so all output from it is superimposed on this offset voltage.

simulate this circuit – Schematic created using CircuitLab
Once you know the peak to peak voltage across the load resistor of the current transformer you can use that to calculate the peak to peak current the current transformer generated (Ohm's law), and thus the current through the central conductor.
This not only gives you the actual current through the conductor, but by simple logical reasoning, also gives you the state of the contactor: no current = contactor is off.
To reduce programming complexity at the cost of increased BOM cost it could be possible to build a simple rectifying and smoothing circuit (i.e., a simple integrating circuit) from diodes and a capacitor (either a single diode and a capacitor as a half-wave rectifier and smoothing, or a full-wave rectifier and smoothing) which will give you a simple DC voltage proportional to the current. Don't forget to take into account the voltage drop of the diode (or diodes) when doing your calculations, of course.
The integrating circuit could also be used, if you don't care about the current, to directly drive a digital input, as long as the voltage generated under normal load is above the threshold (VIH) of the IO pin, and never exceeds the maximum input voltage for the pin (a little over 5V).  Adding a 5.1V zener diode and series resistor can help protect the input. The same should be done to an analog input as well to protect it from overvoltage.

simulate this circuit
One important thing with this integrating circuit, though, is that any downward changes in the current will take time to be reflected in the output. That is caused by the time C1 takes to discharge down to the new voltage level through R1. Balancing these values so you get a reasonable amount of responsiveness yet minimum amount of ripple on the signal will take a little experimentation and calculation.
You can read more about current transformers and interfacing them to an Arduino here.

For interfacing so many sensors to an Arduino you can, depending on if you are wanting to measure the current directly, or integrate the current to a DC voltage and use it as a threshold to a GPIO pin:

Use shift registers (Parallel-to-Serial) for digital threshold reading,
Use IO expanders (eg MCP23017) for digital threshold reading,
Use external ADC chips (eg MCP3208) to provide more ADC inputs, or
Use analog multiplexers (eg CD4051) to switch different analog voltages to a limited number of ADC inputs

Another option is to break your system down into smaller, more manageable, chunks.  Group your signals into small subsections and have each subsection handled by a separate controller - be that an Arduino (maybe a Mini, or a Micro, or something) to handle a small group of signals. These can then feed their data into a more powerful management system (maybe a Raspberry Pi) through a serial protocol of some form (or wirelessly if you want to spend extra money), which then forwards the readings on to your chosen web service.

Yes you can.
There are special ICs, called Shift-In registers to do this job. You can daisy chain 4 of them, each capable of handling 8 outputs or inputs.
The most known is for outputs (e.g. LEDs) which is a 74HC595 (called shift-out register).
For inputs. you can use a CD4021BE. See the Shiftin Example how to use them.
It will cost 3 pins (except VCC/GND) to control 32 inputs, so you need 6 pins for 50 (max 64). You need 50 / 8 = 7 of these ICs, but they are very cheap (10 for about 2 dollars).
Note that you will receive either a 0 or 1, so it's up to you how to detect trip states.

Thanks! can I also read current or voltage using shift register plus some more circuitry?

No, you only get digital signals (0 or 1). I'm not aware of voltage (analog) readings... in that case you might need ADC converters probably. The Uno has 5, if you need more, you need a chip that has multiple ADC channels, but I don't have experience with that.


text:
High pass filtering accelerometer data on Arduino
I'm trying to use an accelerometer for user input to a device. The idea is that the user input will be tied to "taps" on the accelerometer, one tap means something, two taps something else, etc.
I'm using an Adafruit Feather M0 as my microcontroller, controlling an accelerometer that feeds me x,y,z-data at a sampling rate of 100 Hz. I now then want to high pass filter the data with a cutoff frequency of 10 Hz, since taps on the accelerometer give rise to much higher frequencies than other "noise", such as movement.
The accelerometer uses a FIFO buffer to output the data, so I collect 20 samples at a time, and I want to filter those 20 samples with a high pass filter to see if there is a tap within that sampling window. I am currently using the filter function on Arduino playground, https://playground.arduino.cc/Code/Filters.
However, and here is my problem; When I implement this in my code, the filtering "restarts" each window, so that my filtered data looks like this:
[X], [Y], [Z]
0.00,0.00,0.00
-39.67,94.13,-85.18
-29.89,71.66,-64.18
-24.02,53.99,-49.08
-17.39,40.78,-37.09
-13.00,30.51,-27.74
-9.80,22.99,-20.91
-7.58,17.00,-16.17
-7.01,13.88,-14.01
-4.86,12.04,-10.53
-4.02,9.96,-8.71
-2.44,8.05,-7.04
-1.99,6.57,-5.74
-1.60,5.26,-3.80
-2.76,3.27,-4.45
-1.43,2.67,-3.63
-1.16,2.16,-2.13
-0.94,2.55,-1.72
-0.76,1.26,-0.58
-0.62,0.21,-1.29

0.00,0.00,0.00
-40.26,94.51,-84.88
-30.38,70.55,-64.78
-22.13,53.89,-48.04
-17.42,40.60,-37.69
-13.91,29.87,-27.68
-10.99,23.61,-22.67
-10.05,19.04,-16.00
-5.78,14.79,-13.94
-4.69,12.82,-11.31
-3.84,9.69,-9.27
-3.14,7.91,-7.56
-2.52,6.35,-6.08
-2.07,5.22,-4.18
-0.88,4.29,-3.43
-2.35,4.32,-3.62
-0.29,3.54,-2.97
-1.07,2.94,-3.29
-1.63,0.74,-1.02
-0.50,1.38,-1.60

0.00,0.00,0.00
-40.51,95.10,-85.37
-30.32,70.41,-65.39
-22.86,53.10,-49.31
-17.26,40.83,-35.71
-13.45,31.81,-27.81
-9.37,22.43,-20.92
-7.80,17.62,-15.74
-6.50,13.01,-13.10
-4.04,9.56,-8.16
-3.02,7.15,-6.85
-2.29,5.42,-4.43
-2.70,3.63,-4.46
-1.38,4.56,-3.61
-1.14,2.95,-2.16
-1.73,2.38,-1.75
-1.32,2.59,-2.10
-1.05,0.47,-1.67
-0.04,1.12,-1.28
-0.03,0.90,-1.03

I don't understand why this happens, and why the data in the subsequent windows aren't suppressed from the start. I have implemented a very similar solution in Python which works very well with the filtering. Have I misunderstood how Arduinos filtering functions work?
Here is my code:
// Include SPI library
#include <SPI.h>
#include <Filters.h>

// List of addresses: 7-bit adresses, 8th bit is R/W bit, and is set in the functions readRegister and writeRegister.
char X_data_low = 0x28;
char X_data_high = 0x29;
char Y_data_low = 0x2A;
char Y_data_high = 0x2B;
char Z_data_low = 0x2C;
char Z_data_high = 0x2D;

char CTRL_REG1 = 0x20; // Controls data rate selection, low power mode, and X-, Y- and Z-axis enable
char CTRL_REG1_value = 0b00101111; // 0001 1111 = 1 Hz, LP mode, XYZ enable.

char CTRL_REG5 = 0x24; // Enables FIFO mode, among others.
char CTRL_REG5_value = 0b01000000; // 0100 0000, FIFO enabled, all else is zero.

char STATUS_REG = 0x27; // Flags for new XYZ values.

char FIFO_CTRL_REG = 0x2E; // Controls FIFO mode (Bypass, FIFO, Stream, Stream-To-FIFO)
char FIFO_CTRL_REG_value = 0b01000000; // Selects FIFO mode

char FIFO_SRC_REG = 0x2F; // Watermark level, FIFO Overrun, FIFO empty, FSS. Can read FSS to know how many unread samples FIFO buffer contains currently.

//int smpls = 20; // Number of samples

char values[240]; // buffer for storing read values.

int x_val[40]; // Arrays for storing values before filtering
int y_val[40];
int z_val[40];

float filtered_x_val[40]; // Arrays for storing values after filtering
float filtered_y_val[40];
float filtered_z_val[40];

int CS = 5; // Chip select pin

int concat_val = 0b00011111; // For concatenation with values[0] to find number of samples in FIFO buffer
int number_of_FIFO_values; // Number of FIFO samples

// Testing Arduinos own filtering

// filters out changes slower that 10 Hz.
float filterFrequency = 10.0;

// create a one pole (RC) lowpass filter
FilterOnePole highpassFilter_x( HIGHPASS, filterFrequency );
FilterOnePole highpassFilter_y( HIGHPASS, filterFrequency );
FilterOnePole highpassFilter_z( HIGHPASS, filterFrequency );

void setup() {
  // put your setup code here, to run once:
  // Opening pins
  pinMode(22, INPUT_PULLUP); // MISO
  pinMode(24, OUTPUT); // SCK
  pinMode(23, OUTPUT); // MOSI
  pinMode(CS, OUTPUT);  // CS
  pinMode(14, OUTPUT);  // VDD_IO, for use when no breadboard is available to connect both VDD and VDD_IO to 3.3V output
  digitalWrite(CS, HIGH);
  digitalWrite(14, HIGH);
  delay(50);

  // Communication with computer
  Serial.begin(9600);

  // SPI
  SPI.begin();
  SPI.beginTransaction(SPISettings(10000000, MSBFIRST, SPI_MODE0));
  // Loading settings
  delay(10);
  writeRegister(CTRL_REG1,CTRL_REG1_value);
  delay(10);
  writeRegister(CTRL_REG5,CTRL_REG5_value);
  delay(10);
  writeRegister(FIFO_CTRL_REG,FIFO_CTRL_REG_value);
  delay(10);

}

void loop() {
  readRegister(0x2F,1,values);
  number_of_FIFO_values = values[0] & concat_val;

  if (number_of_FIFO_values >= 20){ // It is enough to read high values since LP mode is only 8 bits
    readRegister(0x28,120,values);
    int x_count = 0; // Counters to keep track of which value in x_val, y_val, z_val to be assigned
    int y_count = 0;
    int z_count = 0;
    for(int i=0; i<120; i++){
      if (i % 6 == 1) {
        x_val[x_count] = int(values[i]);
        if(x_val[x_count] > 127)
          x_val[x_count] -= 256;
        x_count += 1;
        }
      if (i % 6 == 3) {
        y_val[y_count] = int(values[i]);
        if(y_val[y_count] > 127)
          y_val[y_count] -= 256;
        y_count += 1;
        }
      if (i % 6 == 5) {
        z_val[z_count] = int(values[i]);
        if(z_val[z_count] > 127)
          z_val[z_count] -= 256;
        z_count += 1;
        }
      }
    Serial.print('\n');
    filtering(x_val,y_val,z_val);
    writeRegister(FIFO_CTRL_REG,0b00000000);
    delay(10);
    writeRegister(FIFO_CTRL_REG,FIFO_CTRL_REG_value);
    delay(10);
  }
}

void filtering(int x_arr[], int y_arr[], int z_arr[]){
    for(int i=0; i<20; i++) {
      highpassFilter_x.input(x_arr[i]);
      highpassFilter_y.input(y_arr[i]);
      highpassFilter_z.input(z_arr[i]);
      filtered_x_val[i] = highpassFilter_x.output();
      filtered_y_val[i] = highpassFilter_y.output();
      filtered_z_val[i] = highpassFilter_z.output();
      Serial.print(filtered_x_val[i]);
      Serial.print(",");
      Serial.print(filtered_y_val[i]);
      Serial.print(",");
      Serial.print(filtered_z_val[i]);
      Serial.print('\n');
    }
  }

//This function will write a value to a register on the sensor.
// Parameters:
//  char registerAddress - The register to write a value to
//  char value - The value to be written to the specified register.
// The bits to specify write or read operation on slave device, and single
// or multiple register reading in reading operation, are included in the
// registeraddress.
// As defined by protocol, the MSB of the address indicates write/read, and the following bit indicate single/multiple reading. Cause ADXL345 support Byte operation,
// The MSB is the 8th bit, the following bit is the 7th bit. (note: if indicating multiple bits reading, ADXL345 will increasing the register address automatically to the
// next successive register like a pointer.
void writeRegister(char registerAddress, char value){
  //Set Chip Select pin low to signal the beginning of an SPI packet.
  digitalWrite(CS, LOW);
  //Transfer the register address over SPI.
  // All ADXL345 register address are smaller than 0100 0000, all are like 00** ****, so that any register address of ADXL345 can be used directly for register write operation
  // without any change on the MSB and its following bit, but the case for reading operation is the opposite.
  // Might need a delay here between CS going low and data transfer.
  SPI.transfer(registerAddress);
  //Transfer the desired register value over SPI.
  // ignored the reture of SPI.transfer in writer operation
  SPI.transfer(value);
  //Set the Chip Select pin high to signal the end of an SPI packet.
  digitalWrite(CS, HIGH);
}

//This function will read a certain number of registers starting from a specified address and store their values in a buffer.
//Parameters:
//  char registerAddress - The register addresse to start the read sequence from.
//  int numBytes - The number of registers that should be read.
//  char * values - A pointer to a buffer where the results of the operation should be stored.
void readRegister(char registerAddress, int numBytes, char * values){
  //Since we're performing a read operation, the most significant bit (bit 7(counting starts from bit 0)) of the register address should be set high.
  char address = 0x80 | registerAddress;
  //If we're doing a multi-byte read, bit 6 (counting starts from bit 0)needs to be set high as well.
  if(numBytes > 1)address = address | 0x40;

  //Set the Chip select pin low to start an SPI packet.
  digitalWrite(CS, LOW);
  //Transfer the starting register address that needs to be read.
  SPI.transfer(address);
  //Continue to read registers until we've read the number specified, storing the results to the input buffer.
  //SPI is full duplex transsmission. Every signle time SPI.transfer can and can only transmit 8 bits. the input parameter will be delived to slave, and it's return will be
  // the data that master device and get from the slave device. The data returned during master device's write operation makes no sense, hence always been ignored by not
  // doing any assignment operation.
  for(int i=0; i<numBytes; i++){
    values[i] = SPI.transfer(0x00);
  }
  //Set the Chips Select pin high to end the SPI packet.
  digitalWrite(CS, HIGH);
}

I opened an issue in the library’s project page.

This filter library is sensitive to the timing of you calling
FilterOnePole::input(). It assumes that the delays between consecutive
calls are the same as the delays between the samples being measured.
C.f. the first statement in the method, which is a call to
micros(). The pauses between your 20-sample buffers are then
interpreted like long times during which the input only changed very
little.
If you are sampling at a constant data rate, I recommend you reimplement
the filter yourself: it is simple enough and it will be way more
efficient than the one you found on Playground.

Edit: Here is a simple implementation of a first-order high-pass
filter like the one in the library, but using a constant sampling rate:
class HigPassFilter
{
public:
    HigPassFilter(float reduced_frequency)
    : alpha(1-exp(-2*M_PI*reduced_frequency)), y(0) {}
    float operator()(float x) {
        y += alpha*(x-y);
        return x-y;
    }
private:
    float alpha, y;
};

You would use it like this:
// Create the filters.
HigPassFilter highpassFilter_x(cutoffFrequency/samplingFerquency);
HigPassFilter highpassFilter_y(cutoffFrequency/samplingFerquency);
HigPassFilter highpassFilter_z(cutoffFrequency/samplingFerquency);

// Apply them.
filtered_x_val[i] = highpassFilter_x(x_arr[i]);
filtered_y_val[i] = highpassFilter_y(y_arr[i]);
filtered_z_val[i] = highpassFilter_z(z_arr[i]);

Huge thanks!
I am however quite the beginner in C++, so I'm wondering that this line in your code do? Specifically, what is alpha in this context?
: alpha(1-exp(-2*M_PI*reduced_frequency)), y(0) {}

@LarsPetersson: It initializes the filter constant alpha to the expression 1-exp(...) and the variable y to zero. This α would be equivalent to 1−ampFactor on the library, which is initialized here. The y is the initial value, which also defaults to zero in that library.

@LarsPetersson, it's called an "initialization list". Google it, and see here for one example description: https://www.cprogramming.com/tutorial/initialization-lists-c++.html

source: Stack Exchange

license: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/3.0/

sort: votes


text:
Play a single sound using music shield
I am working on a music shield, I want to play a sound when a sensor triggers (it is very noob I know) well The music shield manufacturer provides a simple class named MusicPlayer here you can find its source
#include <SD.h>
#include <MusicPlayer.h>
#include  <avr/pgmspace.h>

// change this to match your SD shield or module;
// Arduino Ethernet shield: pin 4
// Adafruit SD shields and modules: pin 10
// Sparkfun SD shield: pin 8

static unsigned char fileBuf[32];
songtype list[15];            //song list
int ledcount;
key keys[5];

VS10XX VS1053;
Sd2Card     card;
SdVolume    volume;
SdFile root;
SdFile file;
playingstatetype playingState;
ctrlStatetype ctrlState;

/* PCM file Header */
unsigned char pcmHeader[44] = {
  'R', 'I', 'F', 'F',
  0xFF, 0xFF, 0xFF, 0xFF,
  'W', 'A', 'V', 'E',
  'f', 'm', 't', ' ',
  0x10, 0, 0, 0,          /* 16 */
  0x1, 0,                 /* PCM */
  0x1, 0,                 /* chan */
  0x40, 0x1F, 0x0, 0x0,   /* sampleRate */
  0x80, 0x3E, 0x0, 0x0,   /* byteRate */
  2, 0,                   /* blockAlign */
  0x10, 0,                /* bitsPerSample */
  'd', 'a', 't', 'a',
  0xFF, 0xFF, 0xFF, 0xFF
};

/**************************************************************/
ISR(TIMER1_OVF_vect)          //Timer1 Service
{
    for(int i=0;i<5;i++)
    {
        keys[i].scanKey();
    }

    if (playingState == PS_PAUSE) digitalWrite(LED, HIGH);
    else if (playingState == PS_IDLE) digitalWrite(LED,LOW);
    else
    if (ledcount-- == 0)
    {
        digitalWrite(LED,!digitalRead(LED));
        ledcount = 500;
    }
}

/**************************************************************/
#define RESOLUTION 65536    // Timer1 is 16 bit
void MusicPlayer::initTimer1(void)        //initialize Timer1 to 100us overflow
{
  TCCR1A = 0;                 // clear control register A
  TCCR1B = _BV(WGM13);        // set mode as phase and frequency correct pwm, stop the timer

  long cycles;
  long microseconds = 500;   //setup microseconds here
  unsigned char clockSelectBits;
  cycles = (F_CPU / 2000000) * microseconds;                                // the counter runs backwards after TOP, interrupt is at BOTTOM so divide microseconds by 2
  if (cycles < RESOLUTION)              clockSelectBits = _BV(CS10);              // no prescale, full xtal
  else if ((cycles >>= 3) < RESOLUTION) clockSelectBits = _BV(CS11);              // prescale by /8
  else if ((cycles >>= 3) < RESOLUTION) clockSelectBits = _BV(CS11) | _BV(CS10);  // prescale by /64
  else if ((cycles >>= 2) < RESOLUTION) clockSelectBits = _BV(CS12);              // prescale by /256
  else if ((cycles >>= 2) < RESOLUTION) clockSelectBits = _BV(CS12) | _BV(CS10);  // prescale by /1024
  else        cycles = RESOLUTION - 1, clockSelectBits = _BV(CS12) | _BV(CS10);  // request was out of bounds, set as maximum

  ICR1 = cycles;
  TCCR1B &= ~(_BV(CS10) | _BV(CS11) | _BV(CS12));
  TCCR1B |= clockSelectBits;                                          // reset clock select register, and starts the clock

  TIMSK1 = _BV(TOIE1);
  TCNT1 = 0;
  sei();                      //enable global interrupt
}

/**************************************************************/
void MusicPlayer::initIO(void)
{
  pinMode(SD_CS_PIN, OUTPUT);
  digitalWrite(SD_CS_PIN, HIGH);

  pinMode(VS_XCS, OUTPUT);
  digitalWrite(VS_XCS, HIGH);

  pinMode(LED, OUTPUT);
  digitalWrite(LED,LOW);

  //keys input
  pinMode(KEY_VD, INPUT);
  pinMode(KEY_BK, INPUT);
  pinMode(KEY_PS, INPUT);
  pinMode(KEY_NT, INPUT);
  pinMode(KEY_VU, INPUT);
  //internal pull-up
  digitalWrite(KEY_VD, HIGH);
  digitalWrite(KEY_BK, HIGH);
  digitalWrite(KEY_PS, HIGH);
  digitalWrite(KEY_NT, HIGH);
  digitalWrite(KEY_VU, HIGH);
}

/**************************************************************/
void MusicPlayer::initSD(void)
{

  char i = 0;
  dir_t p;
  char name[13];

  /* init sd card */
  if(!card.init(SPI_FULL_SPEED, SD_CS_PIN))   //SPI_FULL_SPEED
  {
    Serial.println("SD initialization failed.");
    while(1);
  }
  if (!volume.init(card))
  {
    Serial.println("Could not find FAT16/FAT32 partition.");
    while(1);
  }
  root.openRoot(volume);
  Serial.println("---- songs in TF card (root dir) ----");
  while(root.readDir(&p) != 0)
  {
    SdFile::dirName(p, name);
    char *s = name;
    s = strupr(s);
    if(strstr(s,".MP3")||strstr(s,".WAV")||strstr(s,".WMA")||strstr(s,".OGG")
             ||strstr(s,".AAC"))
    {
        uint32_t curPos = root.curPosition();
        uint16_t index = (curPos - 32) >> 5;
        if (file.open(&root,index, O_READ))
        {
            file.close();
            strncpy(list[i].name, name, 13);
            list[i].index = index;
            Serial.println(list[i++].name);
        }
    }
  }
  Serial.println();
  MaxSong = (i-1);
}

/**************************************************************/
void MusicPlayer::begin(void)
{
    keys[0].setKey(KEY_PS,CS_PLAYPAUSE);
    keys[1].setKey(KEY_VD,CS_DOWN);
    keys[2].setKey(KEY_VU,CS_UP);
    keys[3].setKey(KEY_BK,CS_PREV);
    keys[4].setKey(KEY_NT,CS_NEXT);

    initIO();
    initSD();
    VS1053.init();
    initTimer1();  // init timer1
}

/**************************************************************/
void key::setKey(unsigned char io,unsigned char return_value)
{
  _io = io;
  _return_value = return_value;
  _key_st = KS_IDLE;
  _keycnt = 0;
}

/**************************************************************/
void key::scanKey(void)
{
  switch (_key_st)
  {
  case KS_IDLE:
    if (digitalRead(_io) == LOW) _key_st = KS_PRESS;
    _keycnt = 0;
    break;
  case KS_PRESS:
    if (digitalRead(_io) == LOW)
    {
        _keycnt++;
    } else
    {
        if (_keycnt > 20)   //10ms, short press
        {
            ctrlState = (ctrlStatetype)_return_value;
        }
        if (_keycnt > 1000) //50 ms,long press
        {
            if((ctrlStatetype)_return_value == CS_PLAYPAUSE)ctrlState = CS_RECORDING;
        }
        _keycnt = 0;
        _key_st = KS_IDLE;

        if(ctrlState == CS_PLAYPAUSE)
        {
            if(playingState == PS_PAUSE)playingState = PS_PLAY;
            else playingState =PS_PAUSE;
            ctrlState = CS_EMPTY;
        }
        if(ctrlState == CS_RECORDING)
        {
            playingState = PS_RECORDING;
            ctrlState = CS_EMPTY;
        }
    }
    break;
  default:
    break;
  }
}

/**************************************************************/
void MusicPlayer::play()
{

    unsigned char bytes;        // How many bytes in buffer left
    unsigned char n;

    SPI.setClockDivider(SPI_CLOCK_DIV2);
    if(file.open(&root,list[songIndex].index,O_READ))
    {
        Serial.print("Playing ");
        Serial.println(list[songIndex].name);
    }
    else
    {
        Serial.print("Could not open: ");
        Serial.println(list[songIndex].name);
        songIndex ++;
        while(1);
    }

    playingState = PS_PLAY;
    while(bytes = file.read(fileBuf,sizeof(fileBuf)))
    {
        // actual audio data gets sent to VS10xx.
        VS1053.writeData(fileBuf,bytes);

        switch (playingState)
        {
            case PS_PLAY:
                switch(ctrlState)
                {
                    case CS_UP:
                        Vol += 10;
                        if (Vol > MaxVol)Vol = MaxVol;
                        VS1053.writeRegister(SPI_VOL, Vol*0x101);     //Set volume level
                        ctrlState = CS_EMPTY;
                        break;
                    case CS_DOWN:
                        Vol -= 10;
                        if (Vol < 0)Vol = 0;
                        VS1053.writeRegister(SPI_VOL,Vol*0x101);      //Set volume level
                        ctrlState = CS_EMPTY;
                        break;
                    case CS_NEXT:
                        if (++songIndex > MaxSong)songIndex = 0;
                        file.close();
                        VS1053.softReset();
                        ctrlState = CS_EMPTY;
                        return;
                    case CS_PREV:
                        if (--songIndex < 0)songIndex = MaxSong;
                        file.close();
                        VS1053.softReset();
                        ctrlState = CS_EMPTY;
                        return;
                    default:
                        break;
                }
                break;
            case PS_PAUSE:
                while(playingState == PS_PAUSE);         //Pause
                break;
            case PS_RECORDING:
                file.close();
                VS1053.softReset();
                return;
        }

    }
    file.close();
    VS1053.softReset();
    Serial.println("[done!]");
    songIndex++;

}

/**************************************************************/
void Set32(unsigned char *d, unsigned int n) {
  int i;
  for (i=0; i<4; i++) {
    *d++ = (unsigned char)n;
    n >>= 8;
  }
}

/**************************************************************/
void MusicPlayer::recording(char *recfile) {
    unsigned long fileSize = 0;
    unsigned int n;

    VS1053.writeRegister(SPI_BASS, 0x0055);    //set accent
    VS1053.writeRegister(SPI_AICTRL0,8000);    //samplerate 8k
    VS1053.writeRegister(SPI_AICTRL1,0);       //record gain
    VS1053.writeRegister(SPI_AICTRL2,0);       //Set the gain maximum,65536=64X
    VS1053.writeRegister(SPI_AICTRL3,6);       //PCM Mode ,left channel
    VS1053.writeRegister(SPI_CLOCKF,0x2000);   //set clock

    VS1053.writeRegister(SPI_MODE,0x1804);   //mic,Initialize recording
    delay(2);

    VS1053.loadPlugin(recPlugin,sizeof(recPlugin)/sizeof(recPlugin[0]));

    SPI.setClockDivider(SPI_CLOCK_DIV2);
    file.remove(&root,recfile);

    //if(file.open(&root,recfile,O_WRITE|O_CREAT) == NULL)
    if(!file.open(&root,recfile,O_WRITE|O_CREAT))
    {
        Serial.println("Rec open fail");
        return;
    }
    playingState == PS_RECORDING;
    Serial.println("Recording ...");

    while(playingState != PS_PAUSE)
    {
        if ((n = VS1053.readRegister(SPI_HDAT1)) > 0)
        {
                //Make little-endian conversion for 16-bit PCM .WAV files
               for (char i=0; i<n;i++) {
                   unsigned int w = VS1053.readRegister(SPI_HDAT0);
                   file.write((unsigned char)(w & 0xFF));
                   file.write((unsigned char)(w >> 8));
                }
               fileSize += 2*n;
        }
    }
        /* Update file sizes for an RIFF PCM .WAV file */
        file.seekSet(0);
        Set32(pcmHeader+4, fileSize-8);
        Set32(pcmHeader+40, fileSize-36);
        file.write(pcmHeader, sizeof(pcmHeader));
        file.close();

        /* Finally, reset the VS10xx software, including realoading the
             patches package, to make sure everything is set up properly. */
        VS1053.softReset();
}

/**********************************Midi Player Part***************************/
void MusicPlayer::beginMidi(void)
{
  //Init VS105B in Midi Format
  Serial.print("Init vs10xx in MIDI format...");
  VS1053.initForMidi();
  Serial.print("done\r\n");
}

void MusicPlayer::midiWriteData(char cmd, char high, char low)
{
  while(!digitalRead(VS_DREQ));
  digitalWrite(VS_XDCS, LOW);
  midiSendByte(cmd);
  if((cmd & 0xF0) <= 0xB0 || (cmd & 0xF0) >= 0xE0)
  {
    midiSendByte(high);
    midiSendByte(low);
  }
  else
  {
    midiSendByte(high);
  }
  digitalWrite(VS_XDCS, HIGH);
}

void MusicPlayer::midiNoteOn(char channel, char note, char rate)
{
  midiWriteData((0x90 | channel), note, rate);
}

void MusicPlayer::midiNoteOff(char channel, char note, char rate)
{
  midiWriteData((0x80 | channel), note, rate);
}

void MusicPlayer::midiSendByte(char data)
{
  SPI.transfer(0x00);
  SPI.transfer(data);
}

void MusicPlayer::midiDemoPlayer(void)
{
  delay(1000);
  midiWriteData(0xB0, 0x07, 170);   //channel volume

  //GM2 Mode
  Serial.print("Fancy Midi Sounds\r\n");
  midiWriteData(0xB0, 0, 0x78);     //Bank select drums
  for(int instrument = 30 ; instrument < 31 ; instrument++)
  {
    Serial.print(" Instrument: ");
    Serial.println(instrument, DEC);

    midiWriteData(0xC0, instrument, 0);    //Set instrument number. 0xC0 is a 1 data byte command

    //Play notes from F#-0 (30) to F#-5 (90):
    for (int note = 27 ; note < 87 ; note++)
    {
      Serial.print("N:");
      Serial.println(note, DEC);
      //Note on channel 1 (0x90), some note value (note), middle velocity (0x45):
      midiNoteOn(0, note, 127);
      delay(50);

      //Turn off the note with a given off/release velocity
      midiNoteOff(0, note, 127);
      delay(50);
    }

    //delay 100ms between each instruments
    delay(100);
    }
}

This class loops over sd card and plays all of the sounds. but I only want to have a function to play a single file. So I added this function
void MusicPlayer::play(char * path)
{

    unsigned char bytes;        // How many bytes in buffer left
    unsigned char n;

    SPI.setClockDivider(SPI_CLOCK_DIV2);
    if(file.open(&root,path,O_READ))
    {
        Serial.print("Playing ");
        //Serial.println(list[songIndex].name);
    }
    else
    {
        Serial.print("Could not open: ");
        //Serial.println(list[songIndex].name);
        //songIndex ++;
        return;
        //while(1);
    }

    playingState = PS_PLAY;
    while(bytes = file.read(fileBuf,sizeof(fileBuf)))
    {
        // actual audio data gets sent to VS10xx.
        VS1053.writeData(fileBuf,bytes);

        switch (playingState)
        {
            case PS_PLAY:
                switch(ctrlState)
                {
                    case CS_UP:
                        Vol += 10;
                        if (Vol > MaxVol)Vol = MaxVol;
                        VS1053.writeRegister(SPI_VOL, Vol*0x101);     //Set volume level
                        ctrlState = CS_EMPTY;
                        break;
                    case CS_DOWN:
                        Vol -= 10;
                        if (Vol < 0)Vol = 0;
                        VS1053.writeRegister(SPI_VOL,Vol*0x101);      //Set volume level
                        ctrlState = CS_EMPTY;
                        break;
                    case CS_NEXT:
                        //if (++songIndex > MaxSong)songIndex = 0;
                        //file.close();
                        //VS1053.softReset();
                        ctrlState = CS_EMPTY;
                        return;
                    case CS_PREV:
                        //if (--songIndex < 0)songIndex = MaxSong;
                        //file.close();
                        //VS1053.softReset();
                        ctrlState = CS_EMPTY;
                        return;
                    default:
                        break;
                }
                break;
            case PS_PAUSE:
                while(playingState == PS_PAUSE);         //Pause
                break;
            case PS_RECORDING:
                file.close();
                VS1053.softReset();
                return;
        }

    }
    file.close();
    VS1053.softReset();
    Serial.println("[done!]");
    //songIndex++;

}

if I compile the above class with this addition function it will compile but I have no idea if I upload it on arduino it harms the device or not, Does this code works or no?
thanks

You can read the manual/datasheet. Usually they contains an extensive list of DON'Ts and how to safely use your device.

I cannot find anything, that would harm your Uno or shield. When I were in your position, I would simply try, since you haven't changed much from the original play function. But as Look Alterno wrote, if there is a datasheet for your shield, you should also look into it.

all_licenses: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/3.0/


text:
Is the arduino hackable when using communication shields?
Let's say I have an arduino Uno connected to a W5100 ethernet shield. The arduino communicates with the ethernet shield using the tx0 and rx0 pins. When I upload a new script to the arduino using USB, it uses the same tx0 and rx0. So that made me think.
What if I run a script on my arduino that fetches some data from a webpage using HTTP requests but someone manages to hack into my server. Is it possible for the hacker to upload some kind of code to my server, which will erase (when fetched by the arduino) the old script and upload a new arduino script, by making the arduino think it's uploading a new script while it's getting data from the ethernet shield (or other communication shields?)
EDIT: Let's expand the question a bit.. How can I add security to my code to prevent this situation from happening?

Ask on infosec.EE . Use memory buffers prudently and don’t worry.

Everything is hackeable.

You are not expanding the question “quite a bit”: you are opening a vast subject. Lots have been written about how to handle untrusted data, and about the kind of errors you should avoid. In any case, your new question would be more appropriate in https://security.stackexchange.com/

@EdgarBonet Oh no that's not what I meant by that. Just point me in the right direction like you did.

You should be pretty safe, at least as long as your code handles the
incoming data properly.
When you upload a new sketch through USB, the USB-to-serial interface
uses the Arduino pins TX0, RX0 and RESET. Your Ethernet shield, on
the other hand, does not control the RESET pin. Pulling the RESET pin
LOW is needed to make the processor enter the bootloader, which in turn
is needed in order to upload a new program. For pulling this pin low,
the malicious code would need not only to break into the Ethernet
shield's firmware, it would also need a hardware hack to access the
pin.
Now, if your own code is not safe, it is conceivable that the malicious
payload tricks your program into jumping to the bootloader or, as
suggesting by Juraj, into triggering a watchdog reset (which ends up
being equivalent). Thus you should treat anything coming from the
network as potentially malicious.

However, NodeMCU can perform OTA (over the air updates) which is very nice for uploading software remotely, but then anyone can upload a new sketch unless you implement your own security.

@LookAlterno: Right, but at the hardware level, NodeMCU is a completely different beast.

different beast with not open source chinese code deep inside :)

if the downloaded data could trigger the watchdog reset, and the Ethernet shield had STK500 programmer in firmware then a hack hex could be written into avr :)

@Juraj: The downloaded data cannot trigger a watchdog reset. Not by itself: it would need to first exploit a security hole in the user's program. I edited my answer to account for this possibility.

@EdgarBonet, I know, just wanted to point out that writing of the hex is not just sending it to tx/rx

No it's not possible. Assuming you mean this shield (and if you don't, please clarify):

Arduino communicates with both the W5100 and SD card using the SPI bus (through the ICSP header). This is on digital pins 10, 11, 12, and 13 on the Uno and pins 50, 51, and 52 on the Mega.

Further on it mentions:

The shield contains a number of informational LEDs:
...
RX: flashes when the shield receives data
TX: flashes when the shield sends data

That's Rx and Tx on the shield, not the Arduino. Since it does not connect to the Tx/Rx on the Arduino, and since it cannot reset the Arduino, it therefore cannot reprogram it.
If you are worried, disable the BOOTRST fuse on the Arduino so that the bootloader is not active after a reset.
If you are really worried, disable the SPIEN fuse so that you cannot even reprogram it using SPI. Of course, then you won't be able to reprogram it either.
Personally I would be more worried that a cockatoo would come and peck at the shield.

Birds are not to be trusted.

The bird problem is a serious concern.

Great answer!! But now another problem arises, I have an aviary in my garden, should I get rid of it?

If you have cockatoos, I would advise caution. As Wikipedia says: They can be a nuisance in urban areas due to destruction of property ... Birds may also target external wiring and fixtures such as solar water heaters, television antennae and satellite dishes.


text:
ESP8266 - Webserver not working in loop
I have simple example, where in loop is called webServer to handle clients and also text drawing on display.
The thing is that webServer is not responding, but when I remove second part of loop - drawing text to display then web server starts to work normally.
Server does not respond:

 void loop() {
      server.handleClient();
      unsigned long timeNow = millis();
      if ((timeNow > screenChangeTime))  {
          display.clear();
          display.setFont(ArialMT_Plain_16);
          display.setTextAlignment(TEXT_ALIGN_CENTER);
           display.drawString(12, 20,"Loaded: "+String(particles));
           screenChangeTime= timeNow + delay;
           display.display();
      }
    }

Server responds:
void loop() {
      server.handleClient();
}

it is possible that the watchdog triggers because the loop() was taking to long.

Please edit your question to include a Minimal, Complete, and Verifiable example of code, not just snippets. Minimal means you've stripped away irrelevant stuff, just leaving what's needed to show the problem. Complete means all the library names are shown, all the variable declarations, and all the function definitions – so people don't have to waste time guessing what you did or what you meant. Verifiable means it can be compiled and tested, allowing other people to test their theories about the problem

Your way of handling the milliseconds is not correct; at the roll of the millis counter you will have problems. Better to use the usual way (if ((millis() - previousTime) >= screenChangeTime) { previousTime += screenChangeTime; ... })

@frarugi87 while that may be an issue in the long run (in about 49 days 17 hours after power-up) it is unlikely to be the issue here.

@Phil if the screenChangeTime variable is not unsigned long (even if I doubt that it isn't) it has problems much sooner. In any case, I know it is not the issue here, and in fact it was a comment, not an answer.

I have seen this kind of problem on Arduino capable devices like Adafruit Trinket when running out of memory.  I get that you are using the ESP8266 chip but still check to see if you have memory constraints.

My guess is, that you're wasting too much time within the drawing-part.
What is the value for delay? I guess you have a number too low chosen here. And you should really set this new time after you have updated the display by display.display();.
Your webserver doesn't respond because he's not called often enough inside this code.

The purpose of the if statement is to not draw every time, it's also not a blocking function.

license: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/


text:
NRF24l01+ works only when touching its antenna
I have two simple NRF24l01+ (with range of 200m) and two NRF24l01+ with range of 1km.and two socket adapter.
 or what I have
and I have two good library with names RF24 and RF24-master . problem is that I tried a lot of combinations and just one of them worked : two simple NRF24l01+ with their socket adapter and with Getting started example of RF24-master library and only when I touch the antenna of the NRF it can transmit the package and get response. whats the problem? thats with me or my modules have problem?
I've also readed the datasheet and wrote my own code for modules.but it just worked with 1km range NRF24l01+ and most of the packages have failed.
my own code for transmitter :
#include <SPI.h>

#define cePin 7
#define csnPin 8

//#define cePin D0
//#define csnPin D1

int data = 7;

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

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

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

void NRF_transmitterBegin() {

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

  pinMode(cePin, OUTPUT);  //CE
  pinMode(csnPin, OUTPUT);  //CSN
  delay(100);
  digitalWrite(csnPin, 1);
  digitalWrite(cePin, 0);

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

}

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

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

     %battery feature is in progress ...
  */

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

  byte0 = whatIsData;

  switch (whatIsData) {
    case 1: {

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

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

        break;
      }
    case 2: {

        break;
      }
    case 3: {

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

        break;
      }
    default: {
        break;
      }
  }

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

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

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

}

void NRF_monitorRegisters() {

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

}

void setup() {

  Serial.begin(115200);

  NRF_transmitterBegin();
  NRF_monitorRegisters();

}

void loop() {

  NRF_transmit(3 , 15.1 , 0);

  delay(1000);
}

and my code for receiver :
#include <SPI.h>

#define cePin 7
#define csnPin 8

//#define cePin D0
//#define csnPin D1

long int lastTime = 0;

void IRQ() {

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

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

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

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

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

  switch (whatIsData) {
    case 1: {

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

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

        break;
      }
    case 2: {

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

        break;
      }
    case 3: {

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

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

        break;
      }
    default: {

        Serial.println("a problem accured");

        break;
      }
  }

}

void NRF_receiverBegin() {

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

  pinMode(cePin, OUTPUT);  //CE
  pinMode(csnPin, OUTPUT);  //CSN
  delay(100);
  digitalWrite(csnPin, 1);
  digitalWrite(cePin, 0);

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

}

void NRF_startListening() {

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

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

}

void NRF_monitorRegisters() {

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

}

void setup() {

  Serial.begin(115200);

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

}

void loop() {

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

}

Can you clarify what you mean by "tow" which appears multiple times in your question? See tow. Do you mean "two" or "a"? I understand English may not be your first language, but your question is hard to understand.

thanx and sorry for my bad English :)

just one of them worked - what do you mean by "worked"? What range are you testing over? I've got a few of those and they work fine over 20m or so.

I mean sending package and getting response.they are close to each other but I don't know why they can't communicate. I wrote my own code base on datasheet and now I'm adding it to my post.if U can pls try my code and let me know if it works.

If they are to close the signal will distort and data will be lost. For very short range communication you have to reduce the gain, which is what your hand does.

Sometimes I heard it's better to have some minimum distance of 20-30 cm... I tried the simple ones and got on fast speeds about 5-6 meters. Try also rotating them and not have other electronics/metal nearby.

thanx all.
yeah , when I set PA to Low it works good. But still I can't understand why it doesn't work with 1km NRF or without socket adapter.
I thought it's a perfect module for RF communication but I have alot problem with that.

Those 1km versions have an additional amplifier. So at very short distances, they receive so much signal, they can't understand it. It's like someone shouting in a megaphone next to your ear, and all you can hear is ringing.

thanx Gerben. so I'm gonna try 1km modules far away from each other in next few days.I hope it work

The socket adapters take 5.0v. How much power are you supplying? 3.3 or 5v?

I give it a 5v from arduino and it works well about 95% of the time. but when I give it a 3.3v without socket it doesn't work! and I'm not familiar to stackoverflow so can u pls tell me how I can select a comment as 'useful comment' or it needs a high reputation?


text:
Arduino --> RPI I2C issue
ok, I feel like this should be simple, but I am at a loss
Simple code mock up to send 4 bytes(mimicking a float)  over I2C from Arduino to rpi. I am trying to create a state machine so that I can request certain "registers" containing 4 bytes each. I send a byte from pi to arduino indicating what "register" I want, then read back 4 bytes.  I was attemping to reset the state back to NO_STATE after the end of the switch statement, but it effects the bytes received by the pi, and I dont see how.
#include <Wire.h>
#define SLAVE_ADDRESS 0x04

//States
#define NO_STATE 0x00
#define GET_BAT_TEMP 0x03

byte state = NO_STATE;
void setup() {
  Serial.begin(9600);
  pinMode(13, OUTPUT);
  Wire.begin(SLAVE_ADDRESS);
  Wire.onReceive(receiveData);
  Wire.onRequest(sendData);
}

void loop() {
  delay(100);
}

// callback for received data
void receiveData(int byteCount){

  while(Wire.available()) {
    state = Wire.read();
  }
  Serial.print("Got:");
  Serial.println(state);
}

// callback for sending data
void sendData(){
  Serial.println("Sending...");
  byte b[4]={1,1,1,1};

  switch (state){
    case NO_STATE:
      //bad state   not sure if can return only byte, may need to return 4 zeros or somthing
      Wire.write(0);
      Wire.write(0);
      Wire.write(0);
      Wire.write(0);
      break;
    case GET_BAT_TEMP:
      //send battery temp
      Wire.write(3);
      Wire.write(3);
      Wire.write(3);
      Wire.write(3);
      break;
    default:
      Wire.write(9);
      Wire.write(9);
      Wire.write(9);
      Wire.write(9);
      //send back error code
  }
  //reset state to none
  state=NO_STATE;

}

with this code I receive [3,0,0,0]
if I comment out the line
//state=NO_STATE;

I then receive back [3,3,3,3]
which is what I would expect. But I do not see how reseting the state "after" all the bytes are sent would cause an issue
output from arduino shows entering that function only once, and sending the 4 bytes
Got:3
Sending...
Sending...
Sending...
Sending...

I give you +1 for a well written code, your debugging work and a well formed question.

I'm not an expert, but I think I found why it is not working.
The main problem is that you are using always the same byte (0, 3 or 9) for debugging, so you are not noticing that it is not sending four bytes, but only one, and the function gets called four times. This is obvious however from the reply on the serial interface (+1 for adding it in the question, good work).
What you can do is to track how many bytes you sent, and send the successive one. After the bytes are all sent you can reset back the state. The code can be something like
//States
#define NO_STATE 0x00
#define GET_BAT_TEMP 0x03

byte sentData;
byte batteryLevel[4]={3,4,5,6};

byte state = NO_STATE;
void setup() {
    Serial.begin(9600);
    pinMode(13, OUTPUT);
    Wire.begin(SLAVE_ADDRESS);
    Wire.onReceive(receiveData);
    Wire.onRequest(sendData);
}

void loop() {
  // delay(100); // Useless, let it cycle at its max speed
}

// callback for received data
void receiveData(int byteCount){
    while(Wire.available()) {
        state = Wire.read();
        sentData = 0;
    }
    Serial.print("Got:");
    Serial.println(state);
}

// callback for sending data
void sendData(){
    Serial.println("Sending...");

    switch (state){
        case NO_STATE:
            //bad state   not sure if can return only byte, may need to return 4 zeros or somthing
            Wire.write(0);
            break;
        case GET_BAT_TEMP:
            //send battery temp
            Wire.write(batteryLevel[sentData]);
            if (sentData < 3)
                sentData++;
            else
                //reset state to none
                state=NO_STATE;
            break;
        default:
            Wire.write(9);
            //send back error code
    }
}

I haven't tested it, so forgive any bugs. But I'm sure  you understood the main point.
Just some remarks: the delay is useless (you are not saving energy or other with it, so just remove it); the serial is ok for debugging, but I think you should remove it from the code you will use (not ok to stop the interrupts for such a long time).
And most important: I hope you considered the 5V vs 3.3V voltage problem on the I2C ;)
In any case, I second Look Alterno: good way to ask a question, with all the information needed.
EDIT: as pointed out in the comments, there exist a function to send all the data together. I'm not sure how it behaves in different conditions (e.g. when less bytes are requested), but if you trust the communication the function can be simplified in
// callback for sending data
void sendData(){
    Serial.println("Sending...");

    switch (state){
        case NO_STATE:
            //bad state   not sure if can return only byte, may need to return 4 zeros or somthing
            Wire.write(0);
            break;
        case GET_BAT_TEMP:
            //send battery temp
            Wire.write(batteryLevel, 4);
            state=NO_STATE;
            break;
        default:
            Wire.write(9);
            //send back error code
    }
}

(and the sentData variable becomes useless)

You can use Wire.write(data, len) to send all 4 bytes at once.

@LookAlterno I never used it, so I didn't know it existed ;) in any case the OP was using the single byte version, so I used it too... Thank you for the info, I'll update the answer with this

It was not a criticism, just a collaboration.

If the internal pullups on the arduino side are disabled, there is no reason to worry about the voltage mismatch correct?   Arduino only pulls the SDA line low, letting the pi pull it up to rail voltage at 3.3V.

I must have been really tired last night. Didn't put it together in my head that the interrupt was being triggered again before the remaining data was sent. I have not tired any of this yet, but will mark it correct as it seems right. Will edit it with working code once I am done.

@LookAlterno it was perfectly clear that it was a collaboration :) Thank you

@ChadG Just come later to actually write if it is correct ;) in any case, a lot of arduino boards have pullups soldered on the board; moreover even if the high level is 3.3V, it can be misinterpreted by the arduino (the Vih is IIRC 3V, so there is the possibility that the signal is not correct)

Ok, i will keep that in mind, So far I have not seen any "Bad" data that wasn't caused by bad code.   :)


text:
How to Write a function or Loop or program to receive fixed number of Integers or characters over Serial?
I am want to receive a 5 character hexadecimal input from user over serial port of arduino Uno.
int count = 0;                                    // count = 0
char userInput[5];

void setup()
{
  delay(1000);
  Serial.begin(19200);                            // begin serial port with baud rate 9600bps

}
void loop()
{
  if (Serial.available() > 5)
  {
    Serial.read();
  }

  else if (Serial.available() < 4)
  {
    Serial.read();
  }

  else if (Serial.available() == 5)
  {
    for (int i = 0; i < 5; i++)
    {
      userInput[i] = Serial.read();
    }

    Serial.print("User Input - ");
    Serial.println(userInput);
  }

  delayMicroseconds(10000);
}

But I want to discard the input if user inters less than 5 characters or more than 5?
Since the Serial.flush() have a different meaning now, I can not clear the buffer if user enters less than or more than 5 characters and the characters gets added to next input.
e.g. If I upload above program and entered input in following sequence:
abcde
abcd
abcd
abcd
abcd
abcdef
abcde

I got the following output:
User Input - abcde
User Input - dabcd
User Input - dacbd
User Input - bcdef
User Input - abcde

Two invisible characters appear in output which are not visible but when I copied the output from serial monitor but these characters appear when I copy paste the output into Text Editor.
So How can I modify the program to receive only 5 hex character input from user (Which user will input from Hex Keypad)? And if user enters more or less character I want to clear the input buffer for next user input so that characters from previous input doesn't get added to next one.

Does your keypad or data-entry procedure have an "enter" or submit or other termination indicator which, or is your program supposed to react at the moment the 5th character is pressed/entered? In other words, is there a way for the user to indicate "I'm done" entering characters?

Right Now I test testing this Program on Arduino IDE on Laptop over Serial Monitor.

So right now on IDE I am Pressing "ENTER" key  on laptop keyboard to indicate "I'm Done"
But in future I will modify the program to auto react when 5th character in entered..

The solution now I seek is, How to receive only 5 Character input and reject smaller or bigger input?

You need something to synchronize. You need to know where the begin is of the 5 characters. It can be very simple, for example a 'stx' or a '[' character. Or you can use a character at the end of the 5 characters, for example a carriage return or line feed. If you have no control over the serial keypad, then you can use timeouts to identify the start of the 5 characters. In that case you have to describe very careful all the timeouts and the data.

As noted in the comments, since your prototype is receiving data from the serial port, you need some way for the user to indicate to the program that they are finished entry, since a 4-character entry is a necessary point along the way to a 5-character entry.
What you are doing now, by checking if Serial.available()>5 is letting the serial buffer hold 6 characters before you read from it (note: 5 is not >5), but then your else statement:
else if (Serial.available() < 4)
{
  Serial.read();
}

Clears out the buffer (Serial.read() removes one character from the buffer), so you will never get to 5 characters anyway, unless all 6 characters come in between runs of loop(), which is not likely at 19200 baud.
Not to mention that while data is sitting in the buffer, you don't know what it is and can't act on it. It is better to use the buffer as intended, which is to allow the Arduino to collect serial data, even while your program is working on other things, and then grab any pending data from the buffer as the program loop()s.
You have declared the userInput[5] array to hold user input, but note that if you only declare it at 5 chars long, it cannot hold the null-character terminator that is standard for C-style strings. It would be better to declare this as:
char userInput[6];  // Holds 5 user characters, plus null terminator.

In your loop(), you should copy out the contents of the buffer into your userInput, check the length or for a termination character, such as a carriage return or newline (i.e., pressing 'Enter' on the serial terminal.) and act accordingly. Here is an example, showing just the relevant bits for the user input and hiding the rest in [...]:
char userInput[6];  // Holds 5 user characters, plus null terminator.

void setup() {
  userInput[0] = '\0';  // Initialize string to empty
  Serial.begin(9600);
}

void loop() {
  uint8_t processInput = 0;   // Set to 1 if we have complete entry
  while (Serial.available()>0) {
    char input = Serial.read();
    if (input=='\r' || input=='\n') {
      // Have received a terminating character,
      // Flush the rest of the buffer
      while (Serial.available()) {
        Serial.read();
      }

      processInput = 1;

    } else {
      int s_len = strnlen(userInput, 5); // Get current length of userInput
      if (s_len<5) {
        userInput[s_len++] = input;      // Append character
        userInput[s_len] = '\0';         // Null-terminate string
      } else {
        // User has entered more than 5 characters and no terminating
        // character; here is where you can decide to clear the userInput
        // and start over, or just drop the first character and care
        // about the most recent 5, etc. Here, we will clear the input
        // and start over; The 6th character is dropped/ignored and
        // user input starts again. It is as though the 6th character
        // entered is like pressing Enter, but it does not process
        // the incoming data, beacuse 6 characters is an invalid input.
        userInput[0] = '\0';
        s_len = 0;
        processInput = 0;
        // Invalid input
        Serial.println("Error: invalid data");
      }
    }
  }

  if (processInput) {
    Serial.print("User input - ");
    Serial.println(userInput);

    if (strnlen(userInput, 5)==5) {
      // Do something **here** with the input string!!

      // Reset input string
      userInput[0] = '\0';
    } else {
      // Invalid input
      userInput[0] = '\0';
      Serial.println("Error: invalid data");
    }
    processInput = 0;
  }
}

Note, this code is not fully tested and may contain bugs. In particular, I did not intensely check if the while (Serial.available()) {} properly handles a lot of extra data.
One final note, you don't need the delay() with this code.
EDIT:
I tried the sample code above and it had a couple of bugs, one of which was that after a successful 5-digit entry, the input string was not reset to empty. I have now updated the code and it's a valid, working program to receive and process a 5-character input on the serial port and to toss an error if fewer than 5 or more than 5 characters are entered. Entry is terminated with a carriage return or newline (enter key).

else if (Serial.available() < 4)
{
Serial.read();
}
Sorry it is < 5. Now Program rejects all entries below 5 characters. But if user enters more than 5 characters the 1st character is neglected and only 5 characters from 2nd to 6th characters are printed.

Thanks for the answer.. I will try your suggestions with delay and other necessary edits..

I wrote following program, it receives 5 character input from user and if user enters input more than 5 characters then program store only 1st 5 characters and if user inputs less than 5 characters long the it rejects than input altogether..
char userInput[5];
void setup()
{
//delay(1000);
Serial.begin(9600); // begin serial port with baud rate 9600bps
}

void loop()
{
if (Serial.available() < 5)
{
   Serial.read();
}
else if (Serial.available() >= 5)
{
      for (int i = 0; i < 5; i++)
      {
        userInput[i] = Serial.read();
      }
     while (Serial.available() > 0)
     {
       Serial.read();
     }
Serial.print("User Input - ");
Serial.println(userInput);
}
delay(100);
}

The code assumes that the user input always comes in a single block, which is unrealistic. The code must work even if it receive chars one at the time, or two, or three ... whatever.

Not only does it assume user input always comes in a single block, anything less than a full block of 5 characters gets thrown in the garbage and is lost forever.


text:
Adafruit Motor Shield steppers not turning
The Adafruit Motor Shield is connected to 2 steppers which are wired correctly and work when I just use the onestep function. I understand that I cannot drive both at once, so I am using a while loop with two if statements. The Motors were wired:
The left motor was wired:
Green -> m3+
White -> m3-
Red -> m4+
Blue -> m4-
The right motor was wired:
Red -> M2+
Blue -> M2-
Green -> M1+
Black -> M1-
Here is the code:
#include <Wire.h>
#include <Adafruit_MotorShield.h>
#include "utility/Adafruit_MS_PWMServoDriver.h"

Adafruit_MotorShield AFMS = Adafruit_MotorShield();
Adafruit_StepperMotor *leftMotor = AFMS.getStepper(200, 2);
Adafruit_StepperMotor *rightMotor = AFMS.getStepper(200, 1);
//79 steps per half inch
//half inch is a coordinate
//declaring global variables for Hypotenuses (cord lengths)
int leftHyp;
int rightHyp;
int prevX = 0;
int prevY = 0;
//space from shaft to shaft is 30"
//calculating function
void CordCalc(int xCord, int yCord)
{
    Serial.begin(9600);
  //cords start at 0,0
    xCord = xCord - prevX;
    yCord = yCord - prevY;
    int xSquared = sq(xCord);
    int ySquared = sq(yCord);
    int addSquares = xSquared + ySquared;
    int leftHyp = sqrt(addSquares);
  //now for the right
    int rightX = 60 - xCord;
    int rightXsq = sq(rightX);
    int rightSquares = rightXsq + ySquared;
    int rightHyp = sqrt(rightSquares);
  //leftMotor->step(leftHyp * 79, FORWARD, MICROSTEP);
  //rightMotor->step(rightHyp * 79, FORWARD, MICROSTEP);
    int lStepsTaken = 0;
    int rStepsTaken = 0;
    leftHyp = leftHyp * 79;
    rightHyp = rightHyp * 79;
    bool stepsComplete = false;

  //This is the section for moving the Motors
    while(stepsComplete == false) {
        if(lStepsTaken <= leftHyp) {
            leftMotor->onestep(FORWARD,DOUBLE);
            lStepsTaken++;
            Serial.print("Left");
        }

        if(rStepsTaken < rightHyp) {
            rightMotor->onestep(FORWARD,DOUBLE);
            rStepsTaken++;
            Serial.print("Right!");
        }

        if(rStepsTaken >= leftHyp && lStepsTaken >= leftHyp) {
            stepsComplete = true;
        }
    }

    int prevY = yCord;
    int prevX = xCord;
    stepsComplete = false;
}

void setup()
{
// direction from project point of view
    int leftLength = 0;
    int rightLength = 0;
    leftMotor->setSpeed(122);
    rightMotor->setSpeed(122);
    Serial.begin(9600);

    CordCalc(15, 15);
}

void loop()
{
}

Loop is empty on purpose because only need to move to coordinates once.

What is the problem? What your loop() is empty? Edit your question and add your schematic.

you really need to format your code properly. ... correct indentation helps a lot when debugging code

@jsotola. Solved that for you. Ho, my eyes!

The missing line was afms.begin(); which starts communication with the adafruit motor shield.

Remember to accept your own answer to close the question.


text:
Two Arduino boards - one IDE
Have been using UNO MEGA for small projects. Recently bought an UNO for other projects. Can I just go into the IDE an under Tools select UNO and a different port to do projects and rename sketches to keep track of sketches. Do not wish to use boards at the same time.

That's the way to do it.
You need to select the type of board first:

And then the port. You can have both devices connected at the time and select which one you want to program.

With Arduino you can do OTA (Over The Air uploads) to NodeMCU and other ESP8266 based systems.
If you want to run two instances of the IDE, to work with two different boards at the same time, use UECIDE.


text:
changed behaviour in I2C LCD
I reinstalled a previously working sketch to my UNO and now the behaviour of the lcd has changed.
Previously this example worked perfectly:
#include <Wire.h>
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27,16,2);  // set the LCD address to 0x27 for a 16 chars and 2 line display

void setup()
{
  lcd.init();                      // initialize the lcd

  // Print a message to the LCD.
  lcd.backlight();
  lcd.print("Hello, world!");
}

void loop()
{
}

Now it only displays the very first character 'H'
This version does work though:
#include <Wire.h>
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27,16,2);  // set the LCD address to 0x27 for a 16 chars and 2 line display

void setup()
{
  lcd.init();                      // initialize the lcd

  // Print a message to the LCD.
  lcd.backlight();
  lcd.print("H");
  lcd.print("e");
  lcd.print("l");
  lcd.print("l");
  lcd.print("o");
  lcd.print(" ");
  lcd.print("W");
  lcd.print("o");
  lcd.print("r");
  lcd.print("l");
  lcd.print("d");
}

void loop()
{
}

Can anyone shed me any light what is the reason of this change in behaviour and how to solve it?
Running version 1.8.3 on a W7pro PC

Where does it print the letter H, at position 0, 0? If not, try lcd.home(); right after lcd.backlight();.

ok thanks, I tried that but the result is exactly the same

I've tried both of your sketches and they work fine. What happens if you remove the "!" character from your first sketch?

Removing the '!' gives the same problem, I also tried removing the ',' without any improvement..

Have you updated your IDE to a newer version or the LiquidCrystal_I2C library recently?

Yes the IDE was updated pretty recently (v1.8.3), the library is the same as before (LiquidCrystal_I2C1602V1).

ok got it, see my answer, thanks for the suggestions

There seems to be an incompatibility between recent versions of the IDE and the library I was using.
Installing the latest version of the library from GitHub and replacing the lcd.init() command with lcd.begin() in my sketches solved the problem.

Accept your own answer to close this question.

sorry, can't accept yet, I have to wait till tomorrow


text:
Connection Problems with GPRS Shield
I recently bought a GPRS shield from Seeed Studio but was having issues running the programs described in their documentation.  Here is everything you need to know about my shield:
Documentation for GPRS Shield V2.0
Website to purchase GPRS Shield V2.0
I assumed that there was a connection problem. I used the following code to try to debug my SIM900 and its connections to the sim card and the cellular network:
#include <SoftwareSerial.h>
SoftwareSerial gprsSerial(7,8);

void setup(){
  gprsSerial.begin(19200); // GPRS shield baud rate
  Serial.begin(19200);
  delay(500);
}

void loop(){
  if(Serial.available()) {
    switch(Serial.read()) {
      case '0': testSIM900(); break;
        // AT OK
      case '1': testSIMCARD(); break;
        // +CPIN: READY
        // +CREG: 0,1
      case '2': testNETWORK(); break;
        // +CGATT: 1
    }
  }

  if(gprsSerial.available()) Serial.write(gprsSerial.read());
}

void testSIM900() {
  gprsSerial.println("AT");
  // AT OK
  delay(100);

}

void testSIMCARD() {
  gprsSerial.println("AT+CPIN?");
  // +CPIN: READY
  delay(100);
  gprsSerial.println("AT+CREG?");
  // +CREG: 0,1
  delay(100);
}

void testNETWORK() {
  gprsSerial.println("AT+CGATT?");
  // +CGATT: 1
  delay(100);
}

When I entered 0, 1, and 2 into the serial monitor, I got the following response:
AT

OK
AT+CPIN?

+CPIN: READY

OK
AT+CREG?

+CREG: 1,2

OK

+CREG: 0

+CGREG: 0
AT+CGATT?

+CGATT: 0

OK

What does this tell me about the current state of my shield, sim card, and network connection? Is there anything else I can do to isolate issues?

It seems it can't register on the network, GSM modems are power hungry, are you sure you're powering it up with the external power source (through Vin)? Pretty sure the Arduino isn't enough, but I could be wrong, that's a shield that has those issues in mind.
Also try to see the signal strength using AT+CSQ.


text:
convert byte and float to char
I am trying to send sensor values to internet via enc28j60 module and web client example.
My problem is that i chose byte and float form for some sensors i can't convert these values to char form.
Code example below
UVSensorValue = analogRead(A0);               // UVSensorValue is in byte form
concentration = 1.1*pow(duration,3)-3.8*p...  // concentration is in float form

I want to store them in a char variable like this:

param = "uv=5&temp=23.2&dust=0.62..."

And send them here:
ether.browseUrl(PSTR("/measures?"), param, website, browseUrlCallback);

I tried strcpy function or String convention but nothing worked. I know its a silly question however i stuck and cant find solution.
If someone could help me i would be pleased. Thanks in advance!

You want dtostrf()...

In any other C/C++ platform, you can use "%f" as a format specifier when you want to print (or convert to string) a float using printf or its siblings. Any, except in Arduino.
To convert a float you need use dtostrf(),
char * dtostrf(
    double __val,
    signed char __width,
    unsigned char __prec,
    char * __s)

The dtostrf() function converts the double value passed in val into an
  ASCII representationthat will be stored under s. The caller is
  responsible for providing sufficient storage in s.
Conversion is done in the format "[-]d.ddd". The minimum field width
  of the output string (including the possible '.' and the possible sign
  for negative values) is given in width, and prec determines the number
  of digits after the decimal sign. width is signed value, negative for
  left adjustment.
The dtostrf() function returns the pointer to the converted string s.

To convert a byte (or anything not float) to ascii, use snprintf()
int snprintf ( char * s,
               size_t n,
               const char * format,
               ... );

Write formatted output to sized buffer.
Composes a string with the same
  text that would be printed if format was used on printf, but instead
  of being printed, the content is stored as a C string in the buffer
  pointed by s (taking n as the maximum buffer capacity to fill).

You can read the details by yourself, but here is a demo.
The idea is to produce in buffer a traditional C-style string (null terminated). That string you can print or transmit.
The float value is printed in two step. First, we use dtostrf to convert the float value to his ascii representation. Then we use snprintf to include that value (as a string) inside a whole line, latter to be printed.
void setup() {
  Serial.begin(9600);
  while(!Serial);
  Serial.println("Start");

  float value = 123.45;
  byte balue = 128;

  char buffer[80];
  char fValue[16];
  dtostrf(value, 3, 2, fValue);
  snprintf(buffer, sizeof(buffer), "float %s", fValue);
  Serial.println(buffer);
  snprintf(buffer, sizeof(buffer), "byte value is %d", (int) balue);
  Serial.println(buffer);
}

void loop() {

}

It helped me achieve it. Thanks a lot man!!


text:
Using C - How do I make my button press nearly instant without using interrupts
How can I make the press of a button nearly instant, WITHOUT using interrupts or millis() - and NO preset arduino functions, just C.
There is a delay at the end of my while loop of 500ms - perhaps the solution lies in breaking up the delay (NOTE: I need to keep the delays)

Why do you need to keep the delays? Use a variable and check it against the current time, and using state diagram(s) for the part(s) where you think you need the delay for.

Why don't you want interrupts? Interrupts are expected in almost every serious application on embedded devices!

That is the constraint - make the button press nearly instant without using interrupts or millis(). How do I check the variable against the current time using C and not built in Arduino functions?

you can always replace delay() with millis, that constraint sounds like a uni assignment or you getting stuck in an XY problem

millis() is a built in arduino function that I am unable to use due to the constraint.

Who set the constraint?

delay() is also a built in Arduino function.

500ms is lot of time. Very noticeable. With a delay so long, nothing can be instantaneous. Anyway, it doesn't look like a serious problem; it's more like a geek challenge.

due to the constraint .... this smells like school work

@jfpoilpret - actually, interrupts are not all that often directly used to act on user input.  The reason is that user input is often just about the lowest priority input to a system, so you deal with it when you get a chance, after the timing critical tasks.  If interrupts are used, it's to capture and record an event so that it doesn't vanish before it is polled - to take the PC example, to put key events into a buffer - but not to act on them.

For the question at hand with its constraints (whatever their merits or none), what you probably want to do is indeed to divide up the delay, and poll the input in between.  But the question is a bit non-specific for a stack exchange site.  Do give sufficient though to the possibility of contact bounce (if applicable) in your design

You can delay a small period, check button,  delay again.  Loop this until the full delay is achieved

I do this with many things, this is the correct answer.

So then mark it as the correct answer please

Thanks Chad, this is exactly what I did. Thank you for your correct answer.


text:
ESP8266 Connection to Arduino Mega 2560
Im trying to connect my esp8266-01 to my arduino mega 2560 to get the code working from the following video tutorial found on youtube:
https://www.youtube.com/watch?v=zGgUfAB4m24
This is the code Im using from the youtube video:
#include <SoftwareSerial.h>

#define ESP8266_rxPin 4
#define ESP8266_txPin 5

//SSID + KEY
const char SSID_ESP[] = "SSID";
const char SSID_KEY[] = "PASSWORD";

// URLs
const char URL_youtube[] = "GET https://api.thingspeak.com/apps/thinghttp/send_request?api_key=S7QNK85SG9D9YD27 HTTP/1.0\r\n\r\n";
const char URL_current_temp[] = "GET https://api.thingspeak.com/apps/thinghttp/send_request?api_key=S7QNK85SG9D9YD27 HTTP/1.0\r\n\r\n";

//MODES
const char CWMODE = '1';//CWMODE 1=STATION, 2=APMODE, 3=BOTH
const char CIPMUX = '1';//CWMODE 0=Single Connection, 1=Multiple Connections

SoftwareSerial ESP8266(ESP8266_rxPin, ESP8266_txPin);// rx tx

//DEFINE ALL FUNCTIONS HERE
boolean setup_ESP();
boolean read_until_ESP(const char keyword1[], int key_size, int timeout_val, byte mode);
void timeout_start();
boolean timeout_check(int timeout_ms);
void serial_dump_ESP();
boolean connect_ESP();
void get_youtube();
void get_current_temp();
void get_hilo_temp();

//DEFINE ALL GLOBAL VAARIABLES HERE
unsigned long timeout_start_val;
char scratch_data_from_ESP[20];//first byte is the length of bytes
char payload[150];
byte payload_size=0, counter=0;
char ip_address[16];
char youtube_subs[10];
char youtube_views[13];
char current_temp[5];
char hi_temp[5];
char lo_temp[5];

//DEFINE KEYWORDS HERE
const char keyword_OK[] = "OK";
const char keyword_Ready[] = "Ready";
const char keyword_no_change[] = "no change";
const char keyword_blank[] = "#&";
const char keyword_ip[] = "192.";
const char keyword_rn[] = "\r\n";
const char keyword_quote[] = "\"";
const char keyword_carrot[] = ">";
const char keyword_sendok[] = "SEND OK";
const char keyword_linkdisc[] = "Unlink";

//keywords for youtube
const char keyword_html_start_b[] = "b>";
const char keyword_html_end_b[] = "</b";

//keywords for current temp
const char keyword_html_start_temp[] = "p\">";
const char keyword_html_end_temp[] = "<s";
const char keyword_html_start_body = "<body>";
const char keyword_html_end_body = "</body>";

void setup(){//        SETUP     START
  //Pin Modes for ESP TX/RX
  pinMode(ESP8266_rxPin, INPUT);
  pinMode(ESP8266_txPin, OUTPUT);

  ESP8266.begin(9600);//default baudrate for ESP
  ESP8266.listen();//not needed unless using other software serial instances
  Serial.begin(115200); //for status and debug
  delay(5000);//delay before kicking things off

  setup_ESP();//go setup the ESP
}//                    SETUP     END

void loop(){//         LOOP     START

  //get_youtube(); // get youtube views and subs
  //delay(15000);//thingspeak needs ~12 secs before next connection

  get_current_temp();//current temperature
  delay(15000);

}//                    LOOP     END

Whenever I run the code everything just fails and Im not able to send AT commands from my arduino to the ESP.
Im using the following connection between the arduino and the ESP:
**ESP <---------------------> ARDUINO
GND -------------------------- GND
GP2 -------------------------- Not connected
GP0 -------------------------- Not connected
RXD -------------------------- DIGITAL PIN 4
TXD -------------------------- DIGITAL PIN 5
CHPD ------------------------ 3.3V
RST -------------------------- Not connected
VCC -------------------------- 3.3V**

If I connect RESET pin on the arduino to GND and the RX and TX pins on the ESP to digital pins 1 and 0 on the arduino and run the serial monitor and try the AT commands they work fine.
But when I try to run the AT commands by sending them from the arduino to the ESP (by running the code) I get the failed every time. What am I doing wrong?
Here is the link to the full code:
http://www.kevindarrah.com/wp-content/uploads/2015/01/ESP8266_BASE_01_28_15.zip

Watching a video shouldn't be a requirement to understand the question.

You are right I will edit the question by adding the code Im using.

A 35 minutes long video ...

There is a lot of unnecessary code and get_current_temp() isn't even implemented.

And what do you mean "everything just fails"? It doesn't even compile?

Why are you using software serial on a Mega? It has 3 additional hardware serial interfaces.

The code compiles just fine, but the debug info on the serial monitor shows that it failed to connect, etc.

I added the link to the full code, all of the methods are implemented.

(9600);//default baudrate for ESP - it's either 74880 or 115200 - never seen an ESP default at 9600

It works just fine with baud set to 9600 when I connect directly to the ESP from PC

A good coding practice when you fail to get it to work is "KISS" Keep It Simple and Stupid. What I mean is, trim away all unnessecary code and try to get the basics to work. Even start with the serial example that is included in the Arduino IDE.

Further to what @MatsK suggests, what you want is a minimal, complete, verifiable example, for two reasons: because it will make it easier for people to help and hence you're likely to get better help, and because you'll likely find the problem yourself in the process of creating it.

Newb question here but the RX pin of the ESP should be connected on the TX pin on the Arduino and the TX pin on the ESP should be connected on the RX pin of the Arduino ?

yes. did you remove the SoftwareSerial and use a hardware Serial?

How do I do that?, I'm still learning sorry...

I fixed it by changing everything on the code from SoftwareSerial ESP8266 to the hardware serial: Serial1.
I used the pins 18 and 19 of the hardware serial. I also made sure connect the RX pin of the ESP to the TX pin of the Arduino and do the same with the TX pin.


text:
Repairing Analogue Inputs on Uno?
After a long afternoon, chasing a fault on my project, I've come to find that I've damaged 2 out of the 6 Analogue Inputs. Their ADC reading doesn't display 0 when grounded, nor a known ADC value from a sensor.
I've identified the problem to the voltage divider sensors that were connected to these particular Analogue Inputs, I've since researched that topic and made some alterations.
I don't suppose by buying a replacement chip, will solve the problem of 2 bad Analogue Inputs? So I can save the hardware and reduce cost?
Thanks in advance for any help you can provide.
Stu

it is unclear what you are saying ... it seems that you are saying that replacing the atmega328 will not repair the problem ... if that is true, then why do you think so?

The analog inputs are wired directly to the ATMega MCU, so replacing it should fix the problem. Is it socketed or soldered to the board?

new 328s are only about a dollar, but is it worth your time and frustration?

If the Analog input of your Arduino Uno is damaged, then unfortunately you have damaged the pins on the ATMEAGA328P chip directly.
As per the schematic below of Arduino Uno R3, the pins A0 to A5 are connected directly on the Pins 23 to 28 of the ATMEGA328P chip.

Therefore if you say that the 2 out of 6 Analog pins have been damaged then the only way to fix that is to replace the ATMEGA328P chip with a new one.
More can be read here about the UNO's hardware design.
PS. When replacing the ATMEGA328P chip, be sure to program the new chip with the Arduino Bootloader so you can upload sketches to it, otherwise it won't work ;)
Cheers!


text:
Elechouse MP3 shield play random song
Using this code to try and play a random song when someone walks by my distance sensor I get an error, the same song (track 0001) plays every time. Any advice?
#include <SoftwareSerial.h>
SoftwareSerial Geno(7, 8); // Rx, Tx

unsigned char Data[10];
unsigned char i;

// defines pins numbers
const int trigPin = 8;
const int echoPin = 9;

// defines variables
long duration;
int distance;

void setup() {
  delay(1000);
  Geno.begin(9600);
  delay(1000);
  SetVolume(30);
  pinMode(trigPin, OUTPUT); // Sets the trigPin as an Output
  pinMode(echoPin, INPUT); // Sets the echoPin as an Input
  Serial.begin(9600); // Starts the serial communication
}

void playTrack(int num) {
    delay(100);

    Data[0] = 0x7E;
    Data[1] = 0x04;
    Data[2] = 0xA0;
    Data[3] = 0x00;
    Data[4] = 0x00 + num;
    Data[5] = 0x7E;
    Command(Data,5);

    play_pause();

    delay(10000);
}

void SetVolume(int vol) {
   Data[0] = 0x7E; // START
   Data[1] = 0x03; // Length Not 0x02
   Data[2] = 0xA7; // Command
   Data[3] = vol;  // new volume
   Data[4] = 0x7E; // END
   Command(Data,5);
}

void play_pause() {
  Data[0] = 0x7E; // START
  Data[1] = 0x02; // Length
  Data[2] = 0xA3; // Command
  Data[3] = 0x7E; // Mode parameter
  Command(Data,4);
}

void Command(unsigned char *Data, int length) {
  for (int i=0; i<length; i++) {
    Geno.write(Data[i]);
  }
}

void loop() {
  //Assigns a random number
  int song = random(0,200);
  Serial.print("Song is:");
  Serial.print(song);
  Serial.print("\n");
  // Clears the trigPin
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);

  // Sets the trigPin on HIGH state for 10 micro seconds
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);

  // Reads the echoPin, returns the sound wave travel time in microseconds
  duration = pulseIn(echoPin, HIGH);

  // Calculating the distance
  distance = duration * 0.034 / 2;

  Serial.print("Distance: ");
  Serial.println(distance);
  if (distance < 20) {
    playTrack(random(1,25));
  }
  //playTrack(1);
  //playTrack(2);
}

what is the error?

That was bad phrasing on my aprt, the error is it plays the same thing over and over again

start with basic code .... no distance measurement, no random track selection .... only code that plays track 03 (anything other than 01) ... once that works, add random selection .... when that works, add distance sensor code

by its self the play random works but once I add in the code for the distance it play the same song like before, any ideas?

Disclaimer: I know nothing about this media player except what's in this question.  I'd never heard of it before.  The following is simply from observation of the code you posted.
Look at your play_pause() function where the meanings of all the elements are described.
Data[0] = 0x7E;          // START
Data[1] = 0x02;          // Length
Data[2] = 0xA3;          // Command
Data[3] = 0x7E;          //Mode parameter
Command(Data,4);

It seems a message starts with 0x7E, followed by the length , followed by a command and whatever else, followed by another 0x7E.
The length field is 1 less than the total length, so I guess it doesn't include the 'start', or whatever - there are various equivalent ways you could look at it.
In playTrack() you set 6 elements, but with the length element set to 4. You then tell Command() there are 5.  So the last element (0x7E) won't get sent, and the length element which you have sent is wrong anyway.
The receiver is going to get into some weird state, I presume. Perhaps that explains the problem you're seeing.

This is almost definitely a dumb question but I am new to this, where is the length element and where is it set to 4?

I have explained in more detail above.  Hope that makes more sense.

random(1,25) is deterministic. It's PRNG should produce the same sequence of outputs in the same order each time. You need to call randomSeed() at some point, passing it an unpredictable value. Something like:
if(distance < 20){
  randomSeed(micros());
  playTrack(random(1,25));
}

all_licenses: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/


text:
Attiny13 project with leds and electret microphone
I want to make a project similar to this Turn Signal Biking Jacket
.
But, instead of using Arduino Lilypad I want to use an 8 pin attiny13A-SH and want to use one electret microphone instead of the buttons.
I want to use led's only for the left, right and a stop indicator(on the back, i don't want the leds on the sides like the instructable project).
According to me, the leds require 1 pin each and will share a common gnd(that's 4 pins).
The microphone will require 1 additional pin, with 1 going to the gnd (5 pins).
And I might require 2 pins for the power outlet (6 pins out of 8).
Now, i am a newbie in all this stuff so i don't want to go about experimenting with the chips. I am ready to disable the reset pin cause i wont require the chip again. I have got a couple of instructable's to help me in the programming and set-up plan(though they have used Arduino Uno or Lilypad), so I only want to know if it is possible to make the project with the attiny13a chip without the requirement of any additional parts.
Also, as an alternative, i wanted to use these leds instead of the lilypad led's, so i want to know if i can do the model in exactly the same way without using any mofsets etc(i just want 6 leds on each side). I'm extremely sorry for my horrible drawing(First time and no correct tools. used paint!)
ANY HELP IS APPRECIATED.

want to use 1 electret microphone instead of the buttons.

In what way do you want to use the microphone? You do realise, don't you, that an Arduino can't understand speech (or much of anything really) without powerful extra hardware? A microphone by itself is pretty much useless, especially without any form of preamp and signal conditioning.

i only want to know if it is possible to make the project with the attiny13a chip without the requirement of any additional parts.

No, it's not possible. You will require lots more parts. You can't just take an arbitrary chip and connect it to a battery and expect it to work properly. You need to consider correct supply voltages (voltage regulation or boosting depending on your power source), decoupling capacitors, drive circuitry, amplification, signal processing, etc...

i wanted to use these leds instead of the lilypad led's, so i want to know if i can do the model in exactly the same way without using any mofsets etc

Again, no.  Those are 12V LED strips. You need both a 12V supply (and the associated regulation down to 5V to power the ATTiny etc) and MOSFETs (or something similar) to allow the ATTiny to switch that 12V to the LED strips as needed.

Thanks for your reply. But I didn't get your point on the microphone thing since there are loads of voice controlled leds tutorials on the net which use the same mic and the bitvoicer software

Are you going to carry your PC around with you on your bike?

A simple answer would be "No, it's not possible"
You cannot run a single chip independently without any protection and regulating components(e.g. capacitor, regulator, current limiting resistor)
Also by replacing components with other ones, it would require you additional adjustments in the code and also in the hardware(Referring to the replacing buttons with Electret Microphone). There is a reason for the Arduino Lilypad to have additional components so that it can run smoothly and avoid damages to both the user and the device itself.

There are many Tut's on making our own custom Arduino which uses a chip and a capacitor or something. Can I make it like that on a custom based pcb(the chip)

Yes, you could make that, providing that you will use the required necessary basic components. I see that the size matters to you so I would recommend you to try to look also into other Arduino compatible boards like this one here from Adafruit , the Gemma(which is at the size of a Quarter!) and Flora.