body:
I am trying to write code so that 18 LEDs will light up randomly except 2 of them light up together. Am I using `random` wrong? I initialized it to make the random number random.

Here is my code:

<!-- language: lang-c -->

    int timer = 1000;

    int ranndom;

    void setup() {
        // put your setup code here, to run once:
        pinMode(30, OUTPUT);
        pinMode(31, OUTPUT);
        pinMode(32, OUTPUT);
        pinMode(33, OUTPUT);
        pinMode(34, OUTPUT);
        pinMode(35, OUTPUT);
        pinMode(36, OUTPUT);
        pinMode(37, OUTPUT);
        pinMode(38, OUTPUT);
        pinMode(39, OUTPUT);
        pinMode(40, OUTPUT);
        pinMode(41, OUTPUT);
        pinMode(42, OUTPUT);
        pinMode(43, OUTPUT);
        pinMode(44, OUTPUT);
        pinMode(45, OUTPUT);
        pinMode(46, OUTPUT);
        pinMode(47, OUTPUT);

    }

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

        ranndom = random(30, 47);

        if (ranndom == 38 || ranndom == 39) {
            digitalWrite(38, HIGH);
            digitalWrite(39, HIGH);
            delay(timer);

            digitalWrite(38, LOW);
            digitalWrite(39, LOW);
            delay(timer);
        }
        else {
            digitalWrite(ranndom, HIGH);
            delay(timer);

            digitalWrite(ranndom, LOW);
            delay(timer);
        }

    }

title: Random lighting for 18 pin LED

Answers: 0


body:
Could someone help me how to refactor old very complex code ?

Original used just setup and everything else was in single ISR.
But as it was bigger and bigger, code is quite slow and quite random sometimes, even PC emulator did not helpped much (probably some long operations like printing are sometimes interrupted by next interrupt depending on analog values, buttons, etc.).

Is there any guide how to maintain such a project or is there only way out start again from scratch ?

As there are few important regulations also event queue would be needed, but not sure if there is any pattern or a template to start from in case of restart. A-Star 32U4 Micro has <32kB flash and code is hard to fit in yet (there are also big fonts).

*Example of font unpack code, but hope this part is quite ok:*

    void Adafruit_GFX::drawChar(int16_t x, int16_t y, unsigned char c,
      uint16_t color, uint16_t bg, uint8_t size) {
    ...
        uint8_t blockSize = 0;
        if(packed) blockSize = pgm_read_byte(&bitmap[bo++]); // for first char pick 1st bit array only
        BitStreamsReader bitStream(&bitmap[bo++], packed?blockSize:0); // ptr, blockSize(if packed)
        BitXorBuffer rowXorBuf(w); // row XOR buffer (each row is XORed with)
        bool chk;
        for(yy=0; yy<h; yy++) {
            rowXorBuf.rewind();
            for(xx=0; xx<w; xx++) {
                chk = bitStream; // read 1b
                if(packed) chk = rowXorBuf.xorMove(chk); // xor with XOR buffer
                if(chk) {
                    if(size == 1) {
                        writePixel(x+xo+xx, y+yo+yy, color);
                    } else {
                        writeFillRect(x+(xo16+xx)*size, y+(yo16+yy)*size,
                            size, size, color);
                    }
                }
            }
        }
    ...

    class BitStreamsReader {
    public:
     BitStreamsReader(uint8_t *arr, unsigned int maxSize) {
      blockSize = maxSize;
      bitMask = 0x80;
      bytePtr = arr;
      zerosCount = 0;
      remainingBits = 0;
      markBitInit();
     }
     operator bool() {
      if(!blockSize) { // unpacked stream
       bool retVal = !!(pgm_read_byte(bytePtr) & bitMask);
       next();
       return retVal;
      } else if(remainingBits) {
       bool retVal = !!(pgm_read_byte(bytePtr) & bitMask);
       next();
       if(!--remainingBits) {
        markBitInit();
       }
       return retVal;
      } else if(zerosCount) {
       if(!--zerosCount) {
        markBitInit();
       }
       return 0;
      }
      return 0; //throw "??";
     }
    private:
     void markBitInit() {
      if(blockSize) {
       if(pgm_read_byte(bytePtr) & bitMask) {
        remainingBits = blockSize;
       } else {
        zerosCount = blockSize;
       }
       next();
      }
     }
     void next () {
      if(bitMask == 0x01) {
       bitMask = 0x80;
       bytePtr++;
      } else {
       bitMask >>= 1;
      }
     };
     uint8_t *bytePtr, bitMask, zerosCount, remainingBits, blockSize;
    };

    class BitXorBuffer {
    public:
     BitXorBuffer(int bufSize) {
      bufSize = bufSize/8+!!(bufSize&7);
      bitBuf = new uint8_t[bufSize];
      memset(bitBuf, 0, bufSize);
      rewind();
     }
     ~BitXorBuffer() {
      delete[] bitBuf;
     }
     void rewind() {
      bitMask = 128;
      bytePtr = bitBuf;
     }
     bool xorMove(bool by) {
      if(bitMask & *bytePtr) by ^= true;
      *bytePtr |= bitMask;
      if(!by) {
        *bytePtr ^= bitMask;
      }
      nextBit();
      return by;
     }
    private:
     void nextBit() {
      if(bitMask > 1) {
       bitMask >>= 1; // move bit in XOR buffer
      } else {
       bitMask = 128;
       bytePtr++;
      }
     }
     uint8_t *bytePtr, *bitBuf, bitMask;
    };

title: Refactoring bad design?

Answers: 1

body:
I will try to answer your question as good as possible, though it is quite broad.

To my knowing there is no ONE design pattern or template, that fit's all cases. But depending on the actual functions of your code you can go different ways using libraries (which are somewhat like templates in this sense).

You can get easy multitasking by using libraries like [FreeRTOS][1]. You might even find a compatible version of SafeRTOS, a sibling of FreeRTOS, which has a bigger focus on security. Though the whole RTOS thing might not be right for you and it needs your code to be mostly rewritten/redesigned.

Depending on what ISRs are used and what they are for, you might really need to use interrupts to let the device react immediately. In that case you basically have not choice, but to refactor the whole code as described in the comments (moving as much code as possible to the main loop, making the ISR drastically smaller). For this here some general advice:

- First make a graph of the devices function as it should be. Identify code portions that have a common function, but them into blocks, draw arrows between the blocks to show, how they are connected logically. Then identify which portions are really time critical and what the time contrains are (e.g. Do you need the device to react to an event within a few clock cycles or is it ok, if the reaction comes a few us or ms later?). Mark how often the involved events occur at average and at maximum.
- Now look at the code blocks directly. Which of them need interrupts to work and what happens with them, if interrupts are turned of during their operation (since - as you already identified - reactivating interrupts inside an ISR can get very messy). For example with interrupts off, Serial prints will not be send directly (because this relies on interrupts). Instead the libraries buffer will be filled. When the buffer is already full, a print will wait for the buffer to empty a big (which does not happen with interrupts off).
- Move all code, that is not really time critical, into an if statement in the main loop function. The if statement should be activated by a flag, that would be set in the ISR (be sure to declare it volatile).
- Make sure, that there is nothing blocking in your code (no `delay()`, no waiting for an event in an infinite loop). That also might require serious refactoring, but it's important if you want a fast reaction also outside of the ISR. You might want to look into Finite State Machines for this (they are quite easy to implement and a very powerful construct).
- Keep debug prints small, so that it cannot mess up your timing.
- Lastly: Make some documentation. That is mostly reglected, because it is not that rewarding, but it can save many hours for the next programmer, that needs to maintain your code.

That might seem very time consuming, difficult and not like the comprehensive guide you were looking for. That's the reason, why maintaining legacy code is mostly a real pain in the a*** and does cost companies a lot of money.

At one point or another the technical debt has to be paid. The inventor of the code clearly didn't (or he/she would't have written an ISR this big), so now you will most likely have to go the hard way.

  [1]: https://create.arduino.cc/projecthub/feilipu/using-freertos-multi-tasking-in-arduino-ebc3cc


body: Recently I have gotten some Touchscreens to add to my projects and I am very excited to use them. However, I am not sure where I can find a guide to help me create my own GUI with the touchscreens. The touchscreen I am using right now is the HiLetgo 2.4 inch TFT LCD Display Shield with a ILI9341 Driver. I have experience programming GUI's in Python and I feel fairly confident in myself that I can create the GUI's that I want if I had a resource to learn from. Please Let me know if you'd like anymore information. Thank you!

title: TouchScreen GUI Reference Guide Help

Answers: 0


body:
I had assembled a board with esp8266ex bare chip with 4MB eeprom for esp and also can be shared with host MCU. I had gone through some googling and found that using eeprom function I am able to write data in eeprom using esp8266ex. But I had seen the limitation of 4KB. Then I had researched more than I found that there is a way to increase that.

So my question is, Is there are any issue if I changed that 4KB to 2 MB or more in esp8266 library?

I am using arduino IDE for Esp programming.

title: EEPROM Esp8266 Memory Issue

Answers: 0


body:
I am working with an I2C lcd display with an arduino uno board I have connected the gnd pin to gnd of arduino uno and the vcc pin to 5V of arduino uno and the display is not even lighting up there is only a red led lighting up on the back so I tryed connecting the rest of the pins and run a code to detect the i2c display and it worked successfully I got the adress but the lcd did not light up. The lcd display is a new one I bought yesterday here are the pictures:

https://photos.app.goo.gl/x9QPAWig98yLg4DW9

The script I tryed to display text was this one with the [NewLiquidCristal] [1] library:

    //Libraries
    #include <Wire.h>
    #include <LiquidCrystal_I2C.h>

    LiquidCrystal_I2C lcd(0x3F, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);  // Set the
    LCD I2C address, if it's not working try 0x27.

    void setup(){
    lcd.begin(16,2);   // iInit the LCD for 16 chars 2 lines
    lcd.backlight();   // Turn on the backligt (try lcd.noBaklight() to turn it
    off)
    lcd.setCursor(0,0); //First line
    lcd.print("I2C LCD Tutorial");
    lcd.setCursor(0,1); //Second line
    lcd.print("*Ardumotive.com*");
    }

Here is the model nmber of the I2C: PCF8574A And the lcd is a QAPASS Ui also I don't have a spec sheet and the LCD seems to show empty chars when rotating the pot.
  [1]: http://www.ardumotive.com/uploads/1/2/7/2/12726513/lcd_i2c_16x2_tutorial.zip

title: 16/2 arduino I2C lcd display not lighting up?

Answers: 1

body:
Try this:

    #include <Wire.h>
    #include <LiquidCrystal_I2C.h>

    // LiquidCrystal_I2C lcd(0x27, 16, 2);
    // OR
    LiquidCrystal_I2C lcd(0x3F, 16, 2);

    void setup(){
    lcd.begin();
    lcd.backlight();
    lcd.setCursor(5,0);
    lcd.print("TA DAA...!");
    }
    void loop{
    // do nothing here
    }

If that didn't work probably your LCD have a different address than `0x27` which in that case you should run a I2C scanner to show you the addresses of I2Cs that connected to your Arduino:

    #include <Wire.h>
    // I2C scanner

    void setup()
    {
      Wire.begin();

      Serial.begin(9600);
      Serial.println("\nI2C Scanner");
    }

    void loop()
    {
      byte error, address;
      int nDevices;

      Serial.println("Scanning...");

      nDevices = 0;
      for(address = 1; address < 127; address++ )
      {
        // The i2c_scanner uses the return value of
        // the Write.endTransmisstion to see if
        // a device did acknowledge to the address.
        Wire.beginTransmission(address);
        error = Wire.endTransmission();

        if (error == 0)
        {
          Serial.print("I2C device found at address 0x");
          if (address<16)
            Serial.print("0");
          Serial.print(address,HEX);
          Serial.println("  !");

          nDevices++;
        }
        else if (error==4)
        {
          Serial.print("Unknow error at address 0x");
          if (address<16)
            Serial.print("0");
          Serial.println(address,HEX);
        }
      }
      if (nDevices == 0)
        Serial.println("No I2C devices found\n");
      else
        Serial.println("done\n");

      delay(5000);           // wait 5 seconds for next scan
    }

Check the jumper behind the I2C module (plug it out and in again).

Check the voltage of LED using a multimeter if there's no voltage there, *maybe* it's just a "bad LCD" try replacing it.


body:
I want to convert float value to String for send **Udp.Write()**
 method
 and receive another side (esp) with **Udp.read()**
and
Copy in the one Variable for use ..

**please** help me
**Thanks for every answer ^__^**

code :

    void loop () {
        int signal = analogRead (A0) ;
        float Adc = (signal * 3.3) / 4096 ;
        Udp.beginPacket ({192,168,4,1} , 1234) ;
        Udp.write ( " please help me fill this section ") ;
        Udp.endPacket () ;
    }

---

*i have one more problom . . .*

*and in the other side:*

i want take the**Adc** value from **esp1** and **convert char to float** for **Dac**

(*digital analog converter*) with *MCP4725* ..

** i just need put in float value of Adc in a variable for convertation use ..**

*code*:

**void loop ( ) {**

    int noBytes = Udp.parsePacket();

    String received_command = "";

    if ( noBytes ) {

      Udp.read(packetBuffer,noBytes);

      for (int i=1;i<=noBytes;i++){

      received_command += char(packetBuffer[i - 1]);
    }

    Serial.print("packaet receive: ");

    Serial.println(received_command);

    float Adc_value_received = float(received_command); //*helpppp please char-to-float convert*

  **}**

*thanks from everyone* ^__^

title: Float to String Convert in Udp.write() in esp8266

Answers: 1

body:
The Arduino String class can be used to convert to a character string.

    void loop () {
        int signal = analogRead (A0) ;
        float Adc = (signal * 3.3) / 4096 ;
        String msg = String(Adc, 3);

        Udp.beginPacket ({192,168,4,1}, 1234) ;
        Udp.write(msg.c_str());
        Udp.endPacket () ;
    }


body:
My code below reads data from an ADC and 3 digital pins via a Mega and prints to an SD Shield (Deek Robot). I want to be able to read the data every 50ms (20ms ideally). I can't get below 250ms.

I've read countless forum posts regarding the same issue and understand that I need to create 2x 512 byte buffer, store data to one while the other is being written to the SD card. A forum post mentioned using the Adafruit GPS library for an example of double-buffering but I can't seem to find it. Another suggests changing the internal buffer from 64bytes to 256bytes in hardwareserial.cpp but I can't even navigate to it on my w***ows laptop.

I've run dataString.Length and the max length is 38 for the 8 columns of data, plus a long (for recording ms) another byte for the "\t" and 3 bytes of headroom = 46bytes in all, round it up to 50bytes/sample at a 50ms sampling rate is 1000bytes/second. Darn it, I forgot to add the separating-commas between the columns = plus another 7 bytes; call it 55 in total = 1100bytes/second. I know it can be done but I can't do it; not at my current knowledge/skill level.

Thank you in advance for your help.
<!-- language-all: lang-cpp -->
```
//include relevant libraries
#include <EnableInterrupt.h>
#include <SPI.h>
#include <SD.h>

//globally define pins
#define BUSY 3    //purple*
#define RD 4      //yellow* RD+CS tied together
#define RESET 5   //grey*
#define CONVST 6  //green* CONVSTA+CONVSTB soldered together on the board
#define RANGE 7   //blue*   *not permanent - double check!!!*

#define DB0 22
#define DB1 23
#define DB2 24
#define DB3 25
#define DB4 26
#define DB5 27
#define DB6 28
#define DB7 29
#define DB8 30
#define DB9 31
#define DB10 32
#define DB11 33
#define DB12 34
#define DB13 35
#define DB14 36
#define DB15 37

//byte statusLed       = 13;
byte sensorPin1       = 38;
byte sensorPin2       = 40;
byte sensorPin3       = 42;

int sensorValue[8];
int rawData[16];
//change the size  of these arrays to match the amount of channels being read by the ADC
int adcChannel[5];
int adcData[5];
int channelCount=5;

volatile byte pulseCount1;
volatile byte pulseCount2;
volatile byte pulseCount3;

int pulses[3];

// cs pin for sd-shield *NB 53 for Mega
const int chipSelect = 53;
// SCK 52
// MISO 50
// MOSI 11

unsigned long oldTime;

void setup() {             //set up the hardware

  Serial.begin(9600);
  //sd card.....
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }

  Serial.print("Initializing SD card...");

  // see if the card is present and can be initialized:
  if (!SD.begin(chipSelect)) {
    Serial.println("Card failed, or not present");
    // don't do anything more:
    while (1);
  }
  Serial.println("card initialized.");

  enableInterrupt(BUSY, bitBang, FALLING);

  oldTime            = 0;

  pinMode(DB0, INPUT_PULLUP);
  pinMode(DB1, INPUT_PULLUP);
  pinMode(DB2, INPUT_PULLUP);
  pinMode(DB3, INPUT_PULLUP);
  pinMode(DB4, INPUT_PULLUP);
  pinMode(DB5, INPUT_PULLUP);
  pinMode(DB6, INPUT_PULLUP);
  pinMode(DB7, INPUT_PULLUP);
  pinMode(DB8, INPUT_PULLUP);
  pinMode(DB9, INPUT_PULLUP);
  pinMode(DB10, INPUT_PULLUP);
  pinMode(DB11, INPUT_PULLUP);
  pinMode(DB12, INPUT_PULLUP);
  pinMode(DB13, INPUT_PULLUP);
  pinMode(DB14, INPUT_PULLUP);
  pinMode(DB15, INPUT_PULLUP);

  pinMode(RESET, OUTPUT);
  pinMode(CONVST, OUTPUT);
  pinMode(RD, OUTPUT);
  pinMode(RANGE, OUTPUT);
  pinMode(BUSY, INPUT);

  //reset ADC to begin conversion
  digitalWrite(RESET, HIGH);
  delayMicroseconds(10);
  digitalWrite(RESET, LOW);

  digitalWrite(CONVST, LOW);
  digitalWrite(RD, HIGH);
  digitalWrite(RANGE, LOW);
  digitalWrite(BUSY, LOW);

  delayMicroseconds(100);

  // Set up the status LED line as an output
//  pinMode(statusLed, OUTPUT);
//  digitalWrite(statusLed, HIGH);  // We have an active-low LED attached

  pinMode(sensorPin1, INPUT);
  digitalWrite(sensorPin1, HIGH);

  pinMode(sensorPin2, INPUT_PULLUP);
  digitalWrite(sensorPin2, HIGH);

  pinMode(sensorPin3, INPUT_PULLUP);
  digitalWrite(sensorPin3, HIGH);

  pulseCount1        = 0;
  pulseCount2        = 0;
  pulseCount3        = 0;

  oldTime            = 0;

  // the hall effect sensors are configured to trigger on a FALLING state change
  // (transition from HIGH state to LOW state)
  enableInterrupt(sensorPin1, pulseCounter1, FALLING);
  enableInterrupt(sensorPin2, pulseCounter2, FALLING);
  enableInterrupt(sensorPin3, pulseCounter3, FALLING);

}

void loop() {

  //change this value to preffered sampling rate
  if ((millis() - oldTime) == 50) {

    oldTime = millis();

    //Serial.print(millis());
    //Serial.print("\t");

    //tell ADC to start read (converting analogue input to digital output)
    delayMicroseconds(10);
    digitalWrite(CONVST, LOW);
    delayMicroseconds(10);
    digitalWrite(CONVST, HIGH);
    //when read-conversion is complete ADC sends the BUSY pin low triggering the bitBang ISR

    //print ADC data from array within the bitBang ISR to a string
    String adcString = "";
    for(int thisChannel=0; thisChannel<channelCount; thisChannel++){
      adcString += String(adcData[thisChannel]);
      adcString += ",";
    }

    //disable interrupt to access current pulse count
    disableInterrupt(sensorPin1);
    disableInterrupt(sensorPin2);
    disableInterrupt(sensorPin3);
    //grab current pulse count and store in a variable
    pulses[0] = pulseCount1;
    pulses[1] = pulseCount2;
    pulses[2] = pulseCount3;
    //reset pulse count
    pulseCount1 = 0;
    pulseCount2 = 0;
    pulseCount3 = 0;
    //enable interrupt and start incrementing pulse count again
    enableInterrupt(sensorPin1, pulseCounter1, FALLING);
    enableInterrupt(sensorPin2, pulseCounter2, FALLING);
    enableInterrupt(sensorPin3, pulseCounter3, FALLING);

    String pulseString = "";
    for(int i=0; i<3; i++){
      pulseString += String(pulses[i]);
      if (i<2) {
        pulseString += ",";
      }
    }

   String dataString = String(adcString + pulseString);
  // open the file. note that only one file can be open at a time,
  // so you have to close this one before opening another.
  File dataFile = SD.open("dataLog.txt", FILE_WRITE);

  // if the file is available, write to it:
  if (dataFile) {
    dataFile.print(millis());
    dataFile.print(",");
    dataFile.println(dataString);
    dataFile.close();
    // print to the serial port too:
    //Serial.println(dataString);
  }
  // if the file isn't open, pop up an error:
  else {
    Serial.println("error opening dataLog.txt");
  }

 //Serial.println(dataString);

  }
//start again
}

//grabbing ADC data ISR (for n channel)
void bitBang ()  {
  //a for loop to bitbang the values fom the analogue (ADC) channels (maximum 8) sequentially storing them in a variable array (equal to the channels of the ADC)
  for(int thisChannel=0; thisChannel<channelCount; thisChannel++){
  //send ADC read pin low to bitbang the first channel
  digitalWrite(RD, LOW);
  //read the state of the 16 pins and store in a variable
  rawData[0] = digitalRead(DB15);
  rawData[1] = digitalRead(DB14);
  rawData[2] = digitalRead(DB13);
  rawData[3] = digitalRead(DB12);
  rawData[4] = digitalRead(DB11);
  rawData[5] = digitalRead(DB10);
  rawData[6] = digitalRead(DB9);
  rawData[7] = digitalRead(DB8);
  rawData[8] = digitalRead(DB7);
  rawData[9] = digitalRead(DB6);
  rawData[10] = digitalRead(DB5);
  rawData[11] = digitalRead(DB4);
  rawData[12] = digitalRead(DB3);
  rawData[13] = digitalRead(DB2);
  rawData[14] = digitalRead(DB1);
  rawData[15] = digitalRead(DB0);
  //convert into 16bit 2s compliment and store in a variable array
  adcData[thisChannel] = rawData[0] | (rawData[1] << 1) | (rawData[2] << 2) | (rawData[3] << 3) | (rawData[4] << 4) | (rawData[5] << 5) | (rawData[6] << 6) | (rawData[7] << 7) |  (rawData[8] << 8) | (rawData[9] << 9) | (rawData[10] << 10) | (rawData[11] << 11) | (rawData[12] << 12) | (rawData[13] << 13) | (rawData[14] << 14) | (rawData[15] << 15);
  //send ADC pin high to say we have read the first channel
  digitalWrite(RD, HIGH);
  //repeat for n channels
  }
}

//counting pulses ISRs
void pulseCounter1(){
  // Increment the pulse counter
  pulseCount1++;
}
void pulseCounter2(){
  // Increment the pulse counter
  pulseCount2++;
}
void pulseCounter3(){
  // Increment the pulse counter
  pulseCount3++;
}
```

title: Writing to sd card with a sampling rate 50ms or less? I have a sketch that writes to sd every 1s but jams at faster sampling rates. Please help?

Answers: 2

body:
Some tips:

- Do not open the open and close the file in every loop sequence (I think you can use the `flush` command to save/update the file.
- Do not save strings, but save the raw data and pulse string. This will take 16 * 2 (raw data + 3 bytes for the pulse data = 35 bytes per 16 samples, meaning 35 bytes/samples * 20 samples/s = 700 bytes (I think your calculation of 1100 bytes is incorrect).
- Try to avoid string, and even more string concatenation. I don't know if this will be the bottleneck, but in any case String operations are expensive and for concatenation there is a chance (or is always the case) that memory needs to be allocated dynamically. Use a string buffer instead.

body:
So it turns out the actual problem was this line of code
`if ((millis() - oldTime) == 50) {`
it needed to be changed to
`if ((millis() - oldTime >= 50) {`

I really appreciate all the help everyone gave me to get to the bottom of it and especially thankful to @Michel for handing some solid advice to someone who isn't in the know.
Hopefully I will be able to repay in kind to another learner one day.
:D


body:
I'm trying to read a voltage in from a power supply to an Arduino Micro, then send it to an oscilloscope through an I2C (MCP4725). I would use the default pins on the Micro but I want to wire three I2C and the default bus only allows two. As such, I'm trying to use the [SoftI2CMaster library][1]

I've looked through examples and documentation but I can't seem to get it to send any data. I've been successful scanning (from examples) and finding the I2C addresses, so I assume that the trouble is at the end of my code.

Any tips would be greatly appreciated!

    #define SDA_PORT PORTD
    #define SDA_PIN 4 // = A4
    #define SCL_PORT PORTC
    #define SCL_PIN 6 // = A5
    #include <SoftWire.h>

    #define I2C_7BITADDR 0x62 //MCP4725

    SoftWire Wire = SoftWire();

    int aPin;

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

    void loop(void){
      aPin = analogRead(A0); //read in from power supply
      Wire.beginTransmission(I2C_7BITADDR);
      Wire.write(aPin); //send voltage to osc.
      Wire.endTransmission();
    }

  [1]: https://github.com/felias-fogg/SoftI2CMaster

title: Software I2C - sending data

Answers: 1

body:
The main problem seems to be, that you are not adhering to the MCP's communication protocol. You just try to directly and only send the pure analog measurement to it.

Look at this image from page 18 of the MCP4725's [datasheet][1]:

[![I2C protocol description for MCP4725][2]][2]

It describes the operation is Fast Mode, which seems to be the correct mode for this. (Similar descriptions for the other modes can be found below that image). The first byte is done by the SoftWire library, but the following is your responsibility. The
next 2 bytes consist (in this order) of 2 bit's setting the Fast Mode, 2 bit's for the devices power down select (both zero for normal DAC operation) and then the 12 bits of the actual voltage value for the DAC.

At this point I will show another problem with your code. You read an analog voltage with the Arduinos ADC, which is a 10 bit number (of type `int`) and use it in

    Wire.write(aPin);

But the parameter for `Wire.write()` is defined as `uint8_t` (see [line92 in SoftWire.h of the Softwire library][3]), which means, that your `int` value get's casted and you loose all bits above 255 (the lower byte), because `uint8_t` just cannot store more.

**What you have to do:** You should put the I2C data bytes together in your code and then send them. This may look like this:

    byte byte1 = (aPin & 0x0F00) >> 8;
    byte byte2 = (aPin & 0xFF);

This code uses bitwise operators. The `&` will do an AND operation, the `>>` shifts the bits to the right by the amount after the operator. The `0x` denotes a value in hex representation (binary representation would be `0b`). So for the first byte we are doing an AND with the value `0x0F00`, which will give us a value with only the first 4 bits of the second byte of `aPin`. Then we shift the result 8 bits to the right, so that the remaining data is nicely aligned to the right of your byte. We don't need to include the mode bits and power down select bits here, since they are zero anyway. If you want to set them non-zero you could bitwise OR them (of course with the correct shift, so that the bits have the correct position in the resulting byte):

    byte mode_bits = 0b10;
    byte power_down_bits = 0b11;
    byte byte1 = (mode_bits << 6) | (power_down_bits << 4) | (aPin & 0x0F00) >> 8;

Then you can send these bytes out with I2C:

    Wire.beginTransmission(I2C_7BITADDR);
    Wire.write(byte1);
    Wire.write(byte2);
    Wire.endTransmission();

That should work, though note, that I have not tested this. I just read the datasheet, which is always a must read.

**What happened with your original code:** The datasheet states for the command "Write DAC Register" (which uses 4 bytes including the address byte) the following:

> The device ignores any partially received data  bytes  if  the  I2C
> communication with the Master ends before completing the 4th byte.

So it just drops any I2C messages, that are not complete. Though it is not stated clearly, we can be pretty sure, that the same happens also for the other operation modes. You were sending only 1 byte, so the MCP found the message incomplete and ignored it.

---

That said, there is a principle to work around the limit of only 2 devices on the same bus, which I also only learned recently about. You might not wanna go this way here, but it's a great idea and a valid solution to the problem with the limit.

Every MCP has 1 address pin A0, which set's 1 bit of the address, resulting in 2 possible addresses. On an I2C bus there must not be more than 1 device with the same address. But if that doubled address is never called, the bus doesn't have a problem.

You would connect the A0 pins of each MCP to one digital output pin of the Arduino each. By setting the state of these output pins you can change the address of the MCPs (requirement is, that the MCP actually checks the A0 pin during operation, but the datasheet seems to suggest this). Now you keep every A0 pin on one level, so that all MCPs have the same address. To communicate with one, you would change the state of it's A0 pin to change it's address. Now this MCP is the only MCP with this address (all other MCPs have the other address). You can now communicate with it. When you want to communicate with another MCP, you reset the first MCPs A0 pin and then change the next MCPs A0 pin.

That way you make sure, that on one of the two addresses, there will always be 1 MCP at maximum, while you never use the other address. You can use as many MCPs, as you have digital output pins to change their addresses.

  [1]: https://www.sparkfun.com/datasheets/BreakoutBoards/MCP4725.pdf
  [2]: https://i.stack.imgur.com/JGGO6.jpg
  [3]: https://github.com/felias-fogg/SoftI2CMaster/blob/6e8e7043392bed29cd2925d0a19fce5fc5d726c1/SoftWire.h#L92


body:
I have a heater remote that I want to press the buttons of with my Arduino. I am powering both the remote and Arduino from an external 5V source so both grounds are connected.

Currently I have tried using an NPN transistor(TIP122) and it does work but is not very reliable. It probably works 80% of the time but isn't good enough for my purpose. Sometimes nothing happens and sometimes the button is pressed twice for no reason.

These are my connections.[![enter image description here][1]][1]

I have the emitter connected to ground, collector connected to the button and the base connected to the Arduino with a 1k resistor. Are my connections OK?

I've also tried using a PNP transistor but pulling LOW instead of HIGH and LOW instead of HIGH.

The code is very simple, in the setup I have:

    pinMode(4, OUTPUT);
    digitalWrite(4, HIGH);
    delay(20);
    digitalWrite(4, LOW);

Therefore when I restart the Arduino it should press the button, right?

I also have IRLZ44N and IRF540N, would either of these work better?

  [1]: https://i.stack.imgur.com/Qjn6M.jpg

title: How can I use a transistor to "press" a button?

Answers: 2

body:
A glance at the TIP22 datasheet shows that this is a Darlington pair transistor, which means that it has very high DC gain (good), but at the cost of a very high Vbe_ON (bad).  The datasheet shows that the Vbe_ON is 2.5V, which means that the voltage across the 1K is only 2.5V max, which limits the base current to around 2mA.  This is probably not enough for good saturation.  In addition, the Vce_SAT for this device is about 2.0V, which may or may not be enough to look like a good GND to the button circuit.

I think a MOSFET like the IRF540N, connected as shown [here][1] (substitute button circuit for motor) might be a better choice
YMMV

  [1]: https://components101.com/irf540n-pinout-equivalent-datasheet

body:
You really only need one wire and no resistors or mosfet.

I see many answers including expensive mosfets and relays to answer this question. There is a much simpler solution requiring no glue logic or interfacing circuitry. I recently had to install an off-the-shelf ultrasonic humidifier in an incubator/brooder. It is the cheap little home-use aromatherapy type diffuser. It had to be controlled by a relay to turn on and off. The catch is that the control circuit and firmware used in nearly all of these is the same, it can be turned on by a relay in the PID incubator controller but requires a single button press once power is supplied to start the ultrasonic humidifier and fan. three button presses turns the humidifier off and returns it to standby and turns off automatically when it runs out of water. using the arduino to control only the button to bring it out of standby would not lead to reliable operation. I searched for an answer but found none that I could make given I had few parts and was working on a remote farm. This is my solution.

The science behind this and how it works is that the microcontroller does not sense the press of a button, it detects a state change. You may familiarize yourself with this in the arduino tutorials for reading a button press.

Tie the arduino ground to ground in the circuit you want to control. find a 5v rail and power the arduino. no extra power required. There is usually a test pad that will be ground and 5v close to the button you want to control. if not, find the regulator for the microcontroller that you are trying to trigger by tracing the circuit and attach the power rails. I used Digital Pin 2 for the trigger signal. connect d2 to a point near the switch. Ensure there is a resistor of about 600-1000ohm in the circuit between the point and the microcontroller. This should be present on the circuit you are triggering already simply because this is how microcontrollers detect state changes without sinking or sourcing infinite current.

This code will trigger once and then go to sleep. The long delays are to allow for expected debounce code in the microcontroller and allow for boot time. put simply, it switches PD2 between high and low states in high impedance and low impedance states and basically all a switch does is switch between high impedance and low impedance states. This code should trigger pretty much any microcontroller regardless of the specific state required once and then go to sleep.

```
#include <avr/sleep.h>
void setup() {
  pinMode(13, OUTPUT);
}

void loop() {
  pinMode(PD2, INPUT_PULLUP);
  digitalWrite(PD2, HIGH);
  delay(2000);
  pinMode(PD2, OUTPUT);
  digitalWrite(PD2, HIGH);
  digitalWrite(13, HIGH);
  delay(300);
  digitalWrite(13, LOW);
  pinMode(PD2, INPUT_PULLUP);
  digitalWrite(PD2, HIGH);
  delay(300);
  pinMode(PD2, OUTPUT);
  digitalWrite(PD2, LOW);
  digitalWrite(13, HIGH);
  delay(300);
  digitalWrite(13, LOW);
  pinMode(PD2, INPUT_PULLUP);
  digitalWrite(PD2, LOW);
  delay(500);
  sleep_enable();
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  sleep_cpu();
}

```


body:
A newbie here. I am thinking of interfacing Raspberry Pi with Arduino via I2c to control a few servo motor (as RPi have limited PWM pins). Meaning I would send input from RPi to Arduino to allow to the Arduino to control the servo.

The problem is this: When I was testing the I2C communication alone, it worked fine. The RPI can send a char, and the Arduino Uno can receive and recognize it.

However, when I added in the function to get the Arduino to send PWM signals to the servo, then the program becomes wonky (e.g. when I send over "0x1", the Arduino led should light up, when I send "0x2", the led should turn off. However, once I tried to PWM the servo, it flickers a while and does no light up when I send the signals, and the servo just vibrate a bit, instead of turning to intended position).

And the funny thing is, the code runs (meaning the LED turns on/off accordingly) as long as I do not plug in the servo's signal pin to the Arduino.

What am I missing? Why does the PWM seems to interfere with the I2C, and is there a way to get around this?

My code is below, do pardon me if anything is unclear, I will be more than happy to clarify.

Thanks guys!
<!-- language-all: lang-cpp -->

    #include <Wire.h>
    #include <Servo.h>

    Servo myservo_1; // create servo object to control lift servo
    Servo myservo_2; // create servo object to control entry servo
    Servo myservo_3; // create servo object to control exit servo
    // twelve servo objects can be created on most boards

    int statusLED = 0;
    int statusServo = 0;
    int pos;

    const int ledPin = 13; // onboard LED
    const int servo_1 = 3;
    const int servo_2 = 5;
    const int servo_3 = 9;

    static_assert(LOW == 0, "Expecting LOW to be 0");

    void setup() {
      Wire.begin(0x8);                // join i2c bus with address #8
      Wire.onReceive(receiveEvent);   // register event
      pinMode(ledPin, OUTPUT);
      digitalWrite(ledPin, LOW);     // turn LED off

      myservo_1.attach(servo_1);  // attaches the servo on pin 3 to the servo object
      myservo_2.attach(servo_2);  // attaches the servo on pin 5 to the servo object
      myservo_3.attach(servo_3);  // attaches the servo on pin 9 to the servo object

      //Serial.begin(9600);
    }

    void loop() {

      if (statusServo == 1){
        myservo_1.write(90);
        delay(15);
      }

      else if (statusServo == 2){
        myservo_1.write(0);
        delay(15);
      }

      else {
        myservo_1.write(45);
        delay(15);
      }

    }

    // function that executes whenever data is received from master
    // this function is registered as an event, see setup()
    void receiveEvent(int howMany) {

      int c;

      while (Wire.available()) { // loop through all but the last
        c = Wire.read(); // receive byte as a character
      }

      //Serial.println(c);

        if (c == 0x1){
              digitalWrite(ledPin, HIGH); // turn it on
              statusServo = 1;

        }

        else if (c == 0x2){
              digitalWrite(ledPin, LOW); // turn it on
              statusServo = 2;
        }

    }

title: Servo PWM Pin seems to be interfering with Wire.onRequest i2C function

Answers: 0


body:
I have a Vector Nav VN100 IMU sensor that sends data serially UART. I have interfaced it with ATmega32. It receives data (ROLL angel) from the sensor and according to the ROLL angel, it controls a servo motor.

My question, if the sending rate is faster than processing speed of the ATmega32, then  some data from the sensor will be dropped. How to overcome this problem?

title: Rate of serial communication (UART) of a sensor is faster than speed of processing of microcontroller

Answers: 1

body:
When using an embedded processor's hardware implemented [UART][1], it is often the case that the rate at which the software processes the data is a fraction of the [Gross bit rate][2] some times referred to as the [Baud rate][2].  If the UART is configured to handle 8 bit [RS-232][3] where the Gross bit rate is 10000 bits per second, the processor only has to handle data at a faction of that rate.  Perhaps 1/10 given several bits of over head and space between characters.

Processor intervention can be further reduced if the hardware UART contains several bytes of buffering.  For every doubling of the number of hardware supported bytes of buffering, processor interventions events are cut in half.

Beyond this, there are embedded processors in which the UART supports [DMA or Direct Memory Accessing][4].  This is where the hardware UART will write the received data directly into the processor's memory with out need of processor intervention.  This feature is usually only found on feature rich embedded processors.

Study [this PDF][5] to understand the abilities and limitations of the ATmega32 processor.  Specifically the USART section starting on page 140.

  [1]: https://en.wikipedia.org/wiki/Universal_asynchronous_receiver-transmitter
  [2]: https://en.wikipedia.org/wiki/Bit_rate#Gross_bit_rate
  [3]: https://en.wikipedia.org/wiki/RS-232
  [4]: https://en.wikipedia.org/wiki/Direct_memory_access
  [5]: http://ww1.microchip.com/downloads/en/devicedoc/doc2503.pdf


body:
I'm using Arduino Due and I set the analog read and write resolution to 12-bit for better resolution. Basically all I do is to vary PWM duty cycle by controlling analog DC input voltage from 0 to 3.3V. The simple code as it is now works fine as follows:
<!-- language-all: lang-cpp -->

    int pwmPin9 = 9;
    int analogPin0 = 0;
    int val = 0;

    void setup() {

      Serial.begin(9600);

      pinMode(pwmPin9, OUTPUT);  // sets the pin as output
      analogWriteResolution(12);
      analogReadResolution(12);

    }

    void loop() {

      val = analogRead(analogPin0);  // read the input pin
      Serial.println(val);
      analogWrite(pwmPin9, val);

    }

My problem is I need to set the frequency of the PWM output to 25kHz or at least something nearest above 25kHz.

I have been searching forums hours and couldn't find any solution. [Here][1] I came across a way but there is no library called variant.h in my folders. And that code if I include in my script doesn't change anything.
What could be a workaround for this?

(I used to achieve this via this site by using Arduino Uno but for Due couldn't find any working solution)

Edit: I found the file and made the following change in variant.h:

     * PWM
     */
    #define PWM_INTERFACE  PWM
    #define PWM_INTERFACE_ID ID_PWM
    #define PWM_FREQUENCY  20000
    #define PWM_MAX_DUTY_CYCLE 4095
    #define PWM_MIN_DUTY_CYCLE 0
    #define PWM_RESOLUTION  12

    /*
     * TC
     */
    #define TC_INTERFACE        TC0
    #define TC_INTERFACE_ID     ID_TC0
    #define TC_FREQUENCY        20000
    #define TC_MAX_DUTY_CYCLE   255
    #define TC_MIN_DUTY_CYCLE   0
    #define TC_RESOLUTION  8

But it only works for 20kHz. If I set to 25kHz or 30kHz I don't get any error but also don't get any output :((

  [1]: https://folk.uio.no/jeanra/Microelectronics/GettingTheBestOutOfPWMDue.html

title: Trouble with setting the PWM frequency for Arduino Due

Answers: 1

body:
There are a few things to do. I've used this successfully in the past with older projects.

As a side note one can *very* easily change PWM settings on pins with the esp32, a single line of code being `ledcSetup(PWM_Channel_Number, Frequency, resolution)` without ever having to actually dive into modifying variant.h

To Quote [Kerry D. Wong][1]:

> If you take a look at the function PWMC_ConfigureClocks in pwmc.c, you will see that the highest PWM frequency can be accommodated as the function input is 42 MHz, this is because inside the function it calls FindClockConfiguration which in turn ensures that the frequency parameter passed in is less than the MCK frequency. Thus for integer dividers, the highest frequency we can pass in is 42 MHz (with divider 2).

> To achieve the highest output frequency, we can use a one bit PWM which essentially just outputs a square wave with a duty cycle of one. We can then set the prescaler to 2 to obtain an 84 MHz waveform.

    #include <Arduino.h>

    uint32_t pwmPin = 8;
    uint32_t maxDutyCount = 2;
    uint32_t clkAFreq = 42000000ul;
    uint32_t pwmFreq = 42000000ul;

    void setup() {
      pmc_enable_periph_clk(PWM_INTERFACE_ID);
      PWMC_ConfigureClocks(clkAFreq, 0, VARIANT_MCK);

      PIO_Configure(
        g_APinDescription[pwmPin].pPort,
        g_APinDescription[pwmPin].ulPinType,
        g_APinDescription[pwmPin].ulPin,
        g_APinDescription[pwmPin].ulPinConfiguration);

      uint32_t channel = g_APinDescription[pwmPin].ulPWMChannel;
      PWMC_ConfigureChannel(PWM_INTERFACE, channel , pwmFreq, 0, 0);
      PWMC_SetPeriod(PWM_INTERFACE, channel, maxDutyCount);
      PWMC_EnableChannel(PWM_INTERFACE, channel);
      PWMC_SetDutyCycle(PWM_INTERFACE, channel, 1);

      pmc_mck_set_prescaler(2);
    }

    void loop()
    {

> Note that VARIANT_MCK is defined in /arduino-1.5.7/hardware/arduino/sam/variants/arduino_due_x/variant.h as 84000000. PWM_INTERFACE_ID and PWM_INTERFACE are defined in variant.h as ID_PWM and PWM which in turn are defined in /arduino-1.5.7/hardware/arduino/sam/system/CMSIS/Device/ATMEL/sam3xa/include/sam3x8e.h.

> So as the conclusion, the highest stable frequency we can generate using an Arduino Due is 84 MHz. The pictures below show the captured waveforms under different frequencies. For the 21 MHz waveform, pwmFreq is set to 21000000, no prescaler is used. For the 42 Mhz waveform, pwmFreq is set to 420000 with no prescaler. The 84 MHz waveform is generated with set to 42000000 and the prescaler set to 2.

Hope this helps.

  [1]: http://www.kerrywong.com/2014/09/21/on-arduino-due-pwm-frequency/


body:
I have a class containing few `char*` variables:

    char* msgTopic     = "myHome/MSGS";
    char* groupTopic   = "myHome/All";
    char* errorTopic   = "myHome/Err";

but, I wish to have it defined outside the class and not hardcoded (update only `prefixTopic` outside the class,

    char* prefixTopic  = "myHome";
    char* msgTopic     = ""; // also tried-->  char* msgTopic = "AAAAAAAAAAA";
    char* groupTopic   = "";
    char* errorTopic   = "";

and then, down the code to have it defined as:

    sprintf(msgTopic  ,"%s/Messages",prefixTopic);
    sprintf(groupTopic,"%s/All",prefixTopic);
    sprintf(errorTopic,"%s/Errors",prefixTopic);

**BUT**

both ways ( when defining variables as `""`, or just filled it up with chars to allocate space) caused topics to be defined with errors ( mostly - one variable contained both topics ).

Appreciated any help
( I don't think context of class is relevant )

title: Update `char* `

Answers: 1

body:
First, you have to think about using dynamic or pre-allocated strings. Dynamic memory is not recommended for Arduino, so I will use pre-allocated strings.

In that case you need to think about the maximum length, I will take 32 for now:

    #include <stdio.h>

    class YourClass
    {
      static const int MaxTopicLength = 32;

      char _msgTopic[MaxTopicLength];
      char _groupTopic[MaxTopicLength];
      char _errorTopic[MaxTopicLength];

      void FillStrings(const char* prefixTopic);
    };

Than create in your class a function to fill the strings (untested):

    void YourClass::FillStrings(const char* prefixTopic)
    {
      snprintf(_msgTopic  , MaxTopicLength, "%s/Messages", prefixTopic);
      snprintf(_groupTopic, MaxTopicLength, "%s/All"     , prefixTopic);
      snprintf(_errorTopic, MaxTopicLength, "%s/Errors"  , prefixTopic);
    }


body:
[![project][1]][1]
I'm trying to build this project with a simple code.
Object is to hit up button to increment minutes or down to decrement minutes then hit start to start countdown,
while its counting relay will turn On light till counting is done will turn light off and if I hit end button while counting it will end counting and turn off relay.

Here is my try I would appreciate if you could support me.
i can not move to countDown() function in the loop if i press start
I need help to figure out a good technique of declaring functions in void loop in arduino
<!-- language-all: lang-cpp -->

    #include <LiquidCrystal.h>

    LiquidCrystal lcd(1,2,4,5,6,7);

    #define numberOfSeconds(num) ((num/1000) % 60 )
    #define numberOfMinutes(num) (((num/1000) / 60) % 60)

    //unsigned long timeLimit = 3600000; // 1000 ms in 1sec, 60secs in 1min, 60mins in 1hr. so , 1000x60x60 = 3600000ms = 1hr

    const int upBtn = 8;
    const int downBtn = 9;
    const int startBtn = 10;
    const int endBtn = 11;

    int btnPushCounter = 0;
    int minutes;
    int seconds;
    unsigned long minutesGiven;
    unsigned long timeLimit;
    unsigned long timeRemaining;

    int upBtnState = 0;
    int lastUpBtnState = 0;

    int downBtnState = 0;
    int lastDownBtnState = 0;

    int startBtnState = 0;
    int lastStartBtnState = 0;

    int endBtnState = 0;
    int lastEndBtnState = 0;

    bool bPress = false;

    void setup() {

     lcd.begin(16,2);
     pinMode(upBtn, INPUT_PULLUP);
     pinMode(downBtn, INPUT_PULLUP);
     pinMode(startBtn, INPUT_PULLUP);
     pinMode(endBtn, INPUT_PULLUP);

     lcd.clear();
     lcd.setCursor(0,0);
     lcd.print("Minutes : ");
     lcd.print(btnPushCounter);
    }
    void loop() {

        checkUp();
        checkDown();
    //    countDown();
        if(bPress){
          bPress = false;
          displayNumber();
        }
    }

    void displayNumber(){
        lcd.clear();
        lcd.setCursor(0,0);
        lcd.print("Minutes : ");
        lcd.print(btnPushCounter);
    }

    void checkUp(){
      upBtnState = digitalRead(upBtn);
      // compare the buttonState to its previous state
      if (upBtnState != lastUpBtnState) {
        // if the state has changed, increment the counter
        if (upBtnState == HIGH) {
            bPress = true;
          btnPushCounter++;
        }
        delay(50);
      }
      // save the current state as the last state, for next time through the loop
      lastUpBtnState = upBtnState;
    }

    void checkDown(){
      downBtnState = digitalRead(downBtn);

      // compare the buttonState to its previous state
      if (downBtnState != lastDownBtnState && btnPushCounter != 0 ) {
        // if the state has changed, increment the counter
        if (downBtnState == HIGH) {
            bPress = true;
          btnPushCounter--;
        }
        // Delay a little bit to avoid bouncing
        delay(50);
      }
      // save the current state as the last state, for next time through the loop
      lastDownBtnState = downBtnState;
    }

    void checkStart(){
      startBtnState = digitalRead(startBtn);
      if(startBtnState != lastStartBtnState){
        if(startBtnState == HIGH){
          bPress = true;
    //      lcd.
        }
      }
    }

    void countDown() {
    //  unsigned long timeLimit = 3600000;
      minutesGiven = btnPushCounter;
      timeLimit = minutesGiven * 1000 * 60;
      timeRemaining = timeLimit - millis();
      while(timeRemaining > 0){
        seconds = numberOfSeconds(timeRemaining);
        minutes = numberOfMinutes(timeRemaining);
        lcd.setCursor(2,7);
        lcd.print(minutes);
        lcd.print(" ");
        lcd.print(seconds);
        delay(50);
        timeRemaining = timeLimit - millis();
      }
    }

  [1]: https://i.stack.imgur.com/pssjw.jpg

title: Timer Countdown to control relay (multiple functions in void loop)

Answers: 1

body:
I think what you're looking for is to declare your functions near the top of your file, usually before the first function you write, `setup()`, in this case. So add this just above your `setup()` function:

    // Forward function declarations
    void displayNumber(void);
    void checkUp(void);
    void checkDown(void);
    void checkStart(void);
    void countDown(void);

C compilers (and thus, C++ because it was derived from C) read the source code only once through, so any function must become known to the compiler ahead of where it is first called. This would require you to place all low-level functions first, then all functions that call those, then the functions that call those, ..., etc. And there are some cases that even this arrangement won't solve, e.g., functions that call each other (oww, my brain hurts!!). So function declarations are used to avoid this inconvenience.

Declaring a function just means informing the compiler of its name, the parameter types, and the return type -- the actual function code isn't required at this point.


body:
I am currently working with a project using NRF24L01 which I integrated with my Joystick so that I can make it wireless.While transmitting the information in my Joystick to the receiver only analog pin status is getting transmitted where as digital pin status is not getting transmitted.

    Transmitter Code:

    #include <nRF24L01.h>
    #include <printf.h>
    #include <RF24.h>
    #include <RF24_config.h>
    #include <SPI.h>
    #include <Wire.h>

    //Define the digital inputs
    #define tGL1 7
    #define tGL2 6
    #define b1 5
    #define b2 4
    #define b3 3
    #define b4 2

    const int MPU = 0x68; // MPU6050 I2C address
    float AccX, AccY, AccZ;
    float GyroX, GyroY, GyroZ;
    float accAngleX, accAngleY, gyroAngleX, gyroAngleY;
    float angleX, angleY;
    float AccErrorX, AccErrorY, GyroErrorX, GyroErrorY;
    float elapsedTime, currentTime, previousTime;
    int c = 0;

    RF24 radio(9,10);
    const byte address[6]="00001";

    struct Data_Package {
      byte j1PotX;
      byte j1PotY;
      byte j2PotX;
      byte j2PotY;
      byte button1;
      byte button2;
      byte button3;
      byte button4;
      byte tSwitch1;
      byte tSwitch2;
      byte pot1;
      byte pot2;
    };

    Data_Package data;

    void setup() {
      // put your setup code here, to run once:
      Serial.begin(9600);
      initialize_MPU6050();

      radio.begin();
      radio.openWritingPipe(address);
      radio.setAutoAck(false);
      radio.setDataRate(RF24_250KBPS);
      radio.setPALevel(RF24_PA_LOW);

      pinMode(tGL1, INPUT_PULLUP);
      pinMode(tGL2, INPUT_PULLUP);
      pinMode(b1, INPUT_PULLUP);
      pinMode(b2, INPUT_PULLUP);
      pinMode(b3, INPUT_PULLUP);
      pinMode(b4, INPUT_PULLUP);

       data.j1PotX = 127; // Values from 0 to 255. When Joystick is in resting position, the value is in the middle, or 127. We actually map the pot value from 0 to 1023 to 0 to 255 because that's one BYTE value
       data.j1PotY = 127;
       data.j2PotX = 127;
        data.j2PotY = 127;
    //  data.j1Button = 1;
    //  data.j2Button = 1;
      data.pot1 = 1;
      data.pot2 = 1;
      data.tSwitch1 = 1;
      data.tSwitch2 = 1;
      data.button1 = 1;
      data.button2 = 1;
      data.button3 = 1;
      data.button4 = 1;

    }

    void loop() {
      // put your main code here, to run repeatedly:
      data.j1PotX = map(analogRead(A2), 0, 1023, 0, 255); // Convert the analog read value from 0 to 1023 into a BYTE value from 0 to 255
      data.j1PotY = map(analogRead(A1), 0, 1023, 0, 255);
      data.j2PotX = map(analogRead(A3), 0, 1023, 0, 255);
      data.j2PotY = map(analogRead(A0), 0, 1023, 0, 255);
      data.pot1 = map(analogRead(A7), 0, 1023, 0, 255);
      data.pot2 = map(analogRead(A6), 0, 1023, 0, 255);

      data.tSwitch2 = digitalRead(tGL2);

      data.button1 = digitalRead(b1);
      data.button2 = digitalRead(b2);
      data.button3 = digitalRead(b3);
      data.button4 = digitalRead(b4);

      if (digitalRead(tGL1) == 0) {
        read_IMU();    // Use MPU6050 instead of Joystick 1 for controling left, right, forward and backward movements
      }

      radio.write(&data, sizeof(Data_Package));
    }

This is the Reciever Code

    #include <SPI.h>
    #include <nRF24L01.h>
    #include <RF24.h>
    RF24 radio(9, 10);   // nRF24L01 (CE, CSN)
    const byte address[6] = "00001";
    unsigned long lastReceiveTime = 0;
    unsigned long currentTime = 0;
    // Max size of this struct is 32 bytes - NRF24L01 buffer limit
    struct Data_Package {
      byte j1PotX;
      byte j1PotY;
      byte j2PotX;
      byte j2PotY;
      byte pot1;
      byte pot2;
      byte tSwitch1;
      byte tSwitch2;
      byte button1;
      byte button2;
      byte button3;
      byte button4;
    };
    Data_Package data; //Create a variable with the above structure
    void setup() {
      Serial.begin(9600);
      radio.begin();
      radio.openReadingPipe(0, address);
      radio.setAutoAck(false);
      radio.setDataRate(RF24_250KBPS);
      radio.setPALevel(RF24_PA_LOW);
      radio.startListening(); //  Set the module as receiver
      resetData();
    }
    void loop() {
      // Check whether there is data to be received
      if (radio.available()) {
        radio.read(&data, sizeof(Data_Package)); // Read the whole data and store it into the 'data' structure
        lastReceiveTime = millis(); // At this moment we have received the data
      }
      // Check whether we keep receving data, or we have a connection between the two modules
      currentTime = millis();
      if ( currentTime - lastReceiveTime > 1000 ) { // If current time is more then 1 second since we have recived the last data, that means we have lost connection
        resetData(); // If connection is lost, reset the data. It prevents unwanted behavior, for example if a drone has a throttle up and we lose connection, it can keep flying unless we reset the values
      }
      // Print the data in the Serial Monitor
      Serial.print("j1PotX: ");
      Serial.print(data.j1PotX);
      Serial.print("; j1PotY: ");
      Serial.print(data.j1PotY);
      Serial.print("; button1: ");
      Serial.print(data.button1);
      Serial.print("; j2PotX: ");
      Serial.println(data.j2PotX);
    }

When I print the status of the buttons and Joystick in my transmitter(Joystick) I get the correct status of my push button when I press but the status of my push button remain unchanged in the Serial monitor of my Receiver despite there is change other values (I mean the analog value is transmitting correctly)

This the screenshot of my both serial Monitor
[![COM7 is my Transmitter but COM6 is Receiver but change in state of button1 is COM7 is not produced in COM6][1]][1]

  [1]: https://i.stack.imgur.com/uvOGZ.png

title: Arduino digital pin status not transmitting via NRF24L01 where as analog pin status is getting transmitted ,Why?

Answers: 1

body:
As Mikael Patel mentions in the comments: your structures do not match between the transmitter and receiver.

    Transmitter               Receiver
    =====================     =====================
    struct Data_Package {     struct Data_Package {
          byte j1PotX;    ->      byte j1PotX;
          byte j1PotY;    ->      byte j1PotY;
          byte j2PotX;    ->      byte j2PotX;
          byte j2PotY;    ->      byte j2PotY;
          byte button1;   ->      byte pot1;
          byte button2;   ->      byte pot2;
          byte button3;   ->      byte tSwitch1;
          byte button4;   ->      byte tSwitch2;
          byte tSwitch1;  ->      byte button1;
          byte tSwitch2;  ->      byte button2;
          byte pot1;      ->      byte button3;
          byte pot2;      ->      byte button4;
    };                        };

With structures, what matters is *not* what each field is called. What matters is the position of the fields in the list.  When you compile your code all the names are lost. All that is left is where in the list each entry is.

The best way of avoiding this problem is to have a single header file (make it a library so it's easy to share) that contains the packet structure. Then if you ever make any changes to the packet all the sketches that use it see that change the next time you compile them.


body:
This is the timer part of my code:

    int onHourONE = 11;
    int onMinuteONE = 00;
    int offHourONE = 23;
    int offMinuteONE = 00;
    byte PWMstatus = 0;

    void setup{}

    void loop{
        if ((now.hour() >= onHourONE) && (now.minute() >= onMinuteONE)) {
          PWMstatus = 1;
        }
        if ((now.hour() >= offHourONE) && (now.minute() >= offMinuteONE)) {
          PWMstatus = 2;
        }
        if (PWMstatus == 1) {
          // do this
        }
        if (PWMstatus == 2) {
          // do that
    }

It's working just fine but the problem is if i set the `offhourONE` less than `onhourONE` it will keep the LED OFF.

for example the time is now 14:00

`onhourONE` and `offminuteONE` is also set on 14:00

`offhourONE` and `offminuteONE` is set on 13:00

So in this case it should keep the LED ON until tomorrow 13:00 **but** it stays OFF obviously because of this statement:

    if ((now.hour() >= offHourONE) && (now.minute() >= offMinuteONE)) {}

I can change that to this:

    if ((now.hour() == offHourONE) && (now.minute() == offMinuteONE)) {}

But then it will only turn OFF the LED at that specific time, in this case if i restart the Arduino like 1 minute after it turned OFF it will turn on again while it should stay off until it reaches the set point of turn ON.

*I know it sounds simple but seems confusing to me, any guidance appreciated...*

title: RTC timer set point problem

Answers: 2

body:
If it overly complicated to use a combination of seconds, minutes and hours for comparisons. For this you can use the time in seconds, as you get it with `now.secondstime()` or `now.unixtime()`. If you don't want to look at the seconds (so only values multiple to 60), you can do an integer division to get the minutes `now.secondstime()/60`.

To calculate the needed limit values from the combination of hour and minutes, just multiply according to the unit. For seconds `(hour*60+minutes)*60`. For minutes `hour*60+minutes`.

body:
You need to add more logic to your program.

As mentioned in another answer you really want to be working with just the highest resolution time interval that matters to you - that is minutes in your case.  Convert your hour and minutes of the day into the number of minutes since midnight:

    onTime = onHourONE * 60 + onMinuteONE;
    offTime = offHourONE * 60 + offHourONE;

And convert the current time to minutes since midnight:

    timeNow = now.hour() * 60 + now.minute();

Now comes the tricky bit, but since you are now just working with single numbers it's far easier.  You now need to work out *what* you are doing.

You have a couple of scenarios:

1. onTime < offTime - eg: 12:00 to 17:00
2. onTime > offTime - eg: 21:00 to 03:00

You need to make your decision in a different way depending on which scenario you are in - and comparing a single number with a single number is so much easier than messing with hours and minutes.

So, you can do something like:

    if (onTime < offTime) {
        if ((timeNow >= onTime) && (timeNow < offTime)) {
          // On!
        } else {
          // Off!
        }
    } else {
        if ((timeNow >= onTime) || (timeNow < offTime)) {
          // On!
        } else {
          // Off!
        }
    }

In English:

* If the start time is before the end time:
  * If the time is both greater than the start time and less than the end time, then it's on.
  * Otherwise it's off.
* Otherwise, of the start time is after the end time:
  * If the time is greater than the start time, *or* it's less than the end time, then it's on.
  * Otherwise it's off.


body:
I want to print a string together with number. My code is

    Serial.println("Test " + index++);
(In `setup()` I initialized variable `index` to 0.) In Java it would output

    Test 0
    Test 1
    Test 2
    Test 3
    ...
But I get this output instead:

    Test
    est
    st
    t

Can anybody explain it to me please?

title: Serial.println() cuts off characters

Answers: 2

body:
`Serial.println()` prints the value of one expression. The expression you passed it was `("Test " + index++).

In C/C++ a character literal such as "Test " evaluates to the memory address its first character. Adding 1 to that address gives the address of the next (or 2nd) character. Adding 2 to it gives the address of the 3rd character, and so on.

To get what you were expecting, the value of the literal, AND the value of the index, you would write:

    Serial.print("Test ");
    Serial.println(index++);

If you had created a String variable with the value "Test ", then the String expression, `("Test " + index++)` would have been evaluated differently: The "+" operator would have concatenated the String "Text ", with the String equivalent of the current value of "index"; but that isn't the way a character literal is treated. There is a C++ String library among the Arduino libraries but it's use is not recommended because Strings get reallocated and copied when they get concatenated, resulting in excessive memory use, and the Arduino has very little memory.

body:
JRobert explains very well why it does not work.

Instead of the Serial.print you also can use the sprintf function in case you need a more complicated string to build, or in case you want to mix two different types in one line:

    char str[100];
    int index = 0;
    sprintf(str, "Test %d", index++);
    Serial.println(str);

Make sure the buffer (100) is big enough to store the full string including the end symbol ('\0').

For safety you also can use:

    snprintf(str, 100, "Test %d", index++);

This will make sure max. 100 characters are filled in (and the remainder is clipped).


body:
I want to code a depth sensor for a little sub that i am working on. I want it to submerge to a any certain depth  for example 2ft. The speed of the motor is to increase by 5 until it reaches the set point given. The problem that I am facing is: **whenever it reaches the set example point of 2ft the motor turns off and the sub resurfaces to the top and doesn't hold the depth .**
What I want is that for whatever speed the motor is at for 2ft depth, to maintain its speed and keep the sub submerge at 2ft.

    #include <MS5837.h>
    #include <Wire.h>
    #include "MS5837.h"
    #include <Servo.h>
    MS5837 sensor;
    Servo vertical_thruster;

    float x;
    float error;
    int pwm = 1525;
    float currentdepth = sensor.depth();
    float recquireddepth = -0.4;  //  set depth u wish to maintain in meters

    void setup() {
          Serial.begin(9600);
         vertical_thruster.attach(6);
         vertical_thruster.writeMicroseconds(1500);
     /////////////////////////////////////////////Bar 30 Configuration ////////////////////////////////////////
      Serial.println("Starting");
      Wire.begin();
     while (!sensor.init()) {
        Serial.println("Init failed!");
        Serial.println("Are SDA/SCL connected correctly?");
        Serial.println("Blue Robotics Bar30: White=SDA, Green=SCL");
        Serial.println("\n\n");
        delay(2000);
      }
      sensor.setModel(MS5837::MS5837_30BA);
      sensor.setFluidDensity(997); // kg/m^3 (freshwater, 1029 for seawater)
    }

    void loop() {

      sensor.read();
      Serial.print("Depth: ");
      Serial.print(currentdepth);
      Serial.println("m");
    error = (currentdepth) - (recquireddepth) ;

    if ( error!=0)
      { pwm +=5;
        vertical_thruster.writeMicroseconds(pwm+=5);
        Serial.println( pwm+=5);
        Serial.print ( " Submerging ");
      }
    if ( error=0){
      vertical_thruster.writeMicroseconds(pwm);
      Serial.print ( "  At Depth");
    }
    else if ( error >-0){
      vertical_thruster.writeMicroseconds(1400);
      Serial.print ( "resurfacing");
      delay(1000);
    }
    }

title: I want to code a depth sensor for arduino

Answers: 2

body:
Your code has several problems:

- You are including the MS5837 library twice. That just doesn't pose a problem, because the library has include guards, that make sure it is only included once.
- At global scope you use `float currentdepth = sensor.depth();`, which calls the function `sensor.depth()`. This will be done before the `setup()` function, so at that time the sensor library does not have any valid depth data. So it's useless. You can just set it to zero.
- In your `loop()` you are doing `sensor.read()`, but then you are never actually getting the new depth value from the library. You are just again using `currentdepth` without changing it ever. You should set the variable to the new value by using `currentdepth = sensor.depth();` after the `sensor.read()`.
- You are using the statement `if ( error=0)`. Using only a single `=` means an assigment. So here the variable `error` get's set to zero and the if statement will not compare it so zero. You have to use a double `=`: `if(error == 0)`.
- `if( error >-0)`: Why are you checking for error being greater than MINUS ZERO. Sure, -0 is a valid integer, but mostly senseless. Also it is questionable, if the logic is correct here, since first you check for error being different than zero. Then you check for it being zero and then (if it is not equal zero) you check for it being greater than zero. If `error` really happens to be greater than zero, you will first write `pwm` to the servo and then directly 1400, which is submerging and resurfacing directly after another in only one loop.
- The whole if structure seems quite off. You should rethink the logic of the program.

---

That said, for reaching a set point of whatever kind it is good to use a PID controller, that will get you to the setpoint rather fast and will keep you there. A PID controller can be done in hardware or software. For implementing a software PID controller on Arduino you can use one of the various PID libraries, for example [this one][1]. Most libraries also contain examples, that show how to use them.

  [1]: https://github.com/br3ttb/Arduino-PID-Library

body:
    #include <MS5837.h>
    #include <Wire.h>
    #include <Servo.h>

    MS5837 sensor;
    Servo vertical_thruster;

    // Variables

    float current_depth ;
    float set_depth = 0.30 ; //  depth u wish to go in meters
    float PID_error = 0;
    float previous_error = 0;
    float elapsedTime,  Time , timePrev;
    float pwmvertical_thruster;
    int PID_value = 0;
    int PID_p = 0;
    int PID_i = 0;
    int PID_d = 0;

    //PID constants
    float kp = 4.1;
    float ki = 0.03;
    float kd = 1.8;

    void setup() {
      Serial.begin(9600);
     vertical_thruster.attach(6);
     Time = millis ();
     vertical_thruster.writeMicroseconds(1500);

    ///Bar 30 Configuration

     Serial.println("Starting");
     Wire.begin();
    while (!sensor.init()) {
    Serial.println("Init failed!");
    Serial.println("Are SDA/SCL connected correctly?");
    Serial.println("Blue Robotics Bar30: White=SDA, Green=SCL");
    Serial.println("\n\n\n");
    delay(2000);
     }
     sensor.setModel(MS5837::MS5837_30BA);
     sensor.setFluidDensity(997); // kg/m^3 (freshwater, 1029 for seawater)
    }

    void loop() {

    // First read the current value of the depth sensor
    sensor.read();
    current_depth = sensor.depth();

    timePrev = Time;
    Time= millis();
    elapsedTime = ( Time - timePrev) / 1000;

    // calculate the error between the set depth and current depth
    PID_error =  set_depth - current_depth ;

    // Calculate the P Value
     PID_p = kp * PID_error;

    // Calculate the i value in a range on +-0.3

     if (-0.3 < PID_error < 0.3 )
      {
      PID_i = PID_i + (ki * PID_error);
      }

    // Calculate the d value
    PID_d = kd*((PID_error - previous_error)/elapsedTime);
    // The total PID value
    PID_value = PID_p + PID_i + PID_d;

    // range for the blue robotics esc

     if ( PID_value < -400)
     {
     PID_value = -400;
      }
      if( PID_value >400)
      {
     PID_value = 400;
      }
    // calcualte the pwm
     pwmvertical_thruster = (1500 + PID_value) || ( 1500 - PID_value);
    if(pwmvertical_thruster < 1500)
     {
      pwmvertical_thruster= 1500;
      }
     if(pwmvertical_thruster > 1900)
      {
       pwmvertical_thruster=1900;
       }
        Serial.print("Depth: ");
        Serial.print(sensor.depth());
        Serial.println(" m");
        vertical_thruster.writeMicroseconds(pwmvertical_thruster);
        Serial. println ( "t\t");
        Serial. println ( pwmvertical_thruster);
         previous_error = PID_error;

       }`


body:
I'm a really passionate beginner with arduino and electronics and I've built a Keypad lock for my room's door (inside the house).

I've used an arduino that activates a motor using a transistor to open the door if the correct pin is entered.

I want to add wifi control to my project. I have a few transistors, relays and ESP01s lying around for the upgrade. I want to use the blynk app and use the ESP01 independently without disturbing or modifying the arduino code. I'll program the ESP01 directly.

These are my requirements:

-A failsafe so I can open the lock via blynk if I forget the pin

-A kill switch that will turn off the arduino if I suspect somebody knows my PIN.

These are my ideas:

-Can I directly connect an ESP GPIO pin to the base of the transistor where the arduino is connected? By doing this can I control the transistor to switch the motor via both the arduino and the ESP 01?

-Can I put a relay module between the arduino and the battery pack and connect it to the ESP? I will connect the relay so that it will disconnect power to the arduino only when powered on. Is this a viable solution for a kill switch?

Any suggestions and ideas about how to go about this will be highly appreciated.

title: Adding WiFi to my Arduino Keypad Lock

Answers: 1

body:
> Can I directly connect an ESP GPIO pin to the base of the transistor where the arduino is connected?

No. You will effectively be connecting two outputs together, and that is very bad.

Instead you will need to add a second transistor in parallel to the first - one controlled by the Arduino and one controlled by the ESP-01.

> Can I put a relay module between the arduino and the battery pack and connect it to the ESP?

Sure. No problem with that.

> I will connect the relay so that it will disconnect power to the arduino only when powered on. Is this a viable solution for a kill switch?

As long as the kill switch doesn't also shut off power to the ESP-01 - otherwise it will just switch on again straight away...


body:
I'm working on a pet project that requires ADC, SD card (SPI interface, SdFat library) and a display in the future (also SPI).

I have put together a piece of code that initializes ADC at the highest clock frequency and uses ADC_IER_DRDY interrupt and double buffering.

I have also put together a piece of code based on one of SdFat examples that inits SD card and benchmarks its speed.

On its own, each piece works just fine. But combined together, it breaks if I enable the ADC interrupt. It causes SdFat to stall, not sure where (I don't have a debugger). Simply disabling the interrupt is enough to let SdFat work just fine, but I need both. I have also set ADC IRQ priority to 0 and most other IRQs to 1, but removing `NVIC_SetPriority` calls does not solve the problem.

Any advice on how to make both ADC and SPI work, with ADC IRQ priority so that I don't miss samples?
I also tried lowering SPI speed from full to 1/16th (SdFat lib has a convenient parameter for this), didn't help.

The code is not long, but a bit too much for inlining into the question, here are Github links.

 - [main.cpp and ADC stuff][1] - just commenting the highlighted line fixes SPI.
 - [SD card stuff][2]. Of note: sometimes it prints "chipselect: 10", sometimes not even that.

**Update:** making ADC handler empty does not resolve the problem, neither SPI nor printing to Serial works.

  [1]: https://github.com/VioletGiraffe/Oscilloscope-Arduino/blob/master/main.cpp#L93
  [2]: https://github.com/VioletGiraffe/Oscilloscope-Arduino/blob/master/sdcard.cpp#L200

title: Combining ADC IRQ with SPI peripherals results in SPI not working

Answers: 0


body:
I'm trying to compile a code to arudino pro micro, I have the right option for compiling like the port and the type of the board,but I get an error,I can't copy

[![error message][1]][1]

  [1]: https://i.stack.imgur.com/KZiIq.png

title: Compile error in Ubuntu 18.04

Answers: 2

body:
This is likely a permission problem.  The user likely does not have permission to read from and write to the port created when plugging in the Arduino.  This can be temporally fixed using the following command:

    sudo chmod 666 /dev/ttyACM0

However, this procedure is only temporary as the port is recreated every time the Arduino is reconnected to the computer.  And upon recreation the permissions are reset to their defaults for security reasons.

A better solution is to determine the group which the port belongs to and to add the users expected to access these connected devices to that group.

Plugin and list the port to determine its group:

    ls -l /dev/ttyACM*

or

    ls -l /dev/ttyUSB*

The group the ports belong to will likely be "dialout".  Add the user to that group:

    usermod -a -G dialout user_name

...where user_name is replaced by the name of the user who needs access to the port.  If you don't know the name of the current user you can use this command:

    whoami

body:
Sorry for the late reply,it worked in the ide that I download from the web,apparently ide from the ubuntu software won't work.
Thank for the answer


body:
I have interfaced AT24c1024 EEprom with ATmega32.AT24c1024, which has 512 pages each of 256 bytes. There are two mode of writing (byte write and page write).

In page write mode, it is capable of writing 256 bytes for page; if we want to write 258 bytes, then the first two bytes in the beginning of that page will be overwritten.

My question is: what should I do to write in the whole EEprom (i.e) if I want to write 300 bytes, I want to writes 256 bytes in a page then continues to the next page and so on?

title: about how to write data in the whole EEprom?

Answers: 1

body:
In that case you write two pages, the first page containing the first 256 bytes and the second page containing the following 34 bytes.

You can do a speed check to see if writing the second page's 34 bytes by using the byte write is faster, but I doubt that.

In case you want to keep from the second page the remainder of the 34 bytes (the 256-34 bytes following), you first read the second page, than you change the first 34 bytes, than write it back.

Also note that there is a limit on the number of writes on a page. This is called page wearing. So if you write these 2 pages very often, you might want to come up with an algorithm to rotate through all the available pages in your EEPROM, and not writing every time to the same 2 pages.

**EXAMPLE**

Assume you want to write totalBytesToWrite:

    // Calculate the number of pages to write, round up.
    int pagesToWrite = int((totalBytesToWrite + 255) / 256;

    for (int page = 0; page < pagesToWrite; page++) // Current page to be written
    {
        // Calculate number of bytes to be written in this page, for the last page, write remaining bytes, otherwise 256
        int pageBytesToWrite = (page == pagesToWrite - 1 ? totalBytesToWrite % 256 : 256;

        // Write page (btw, I do not know what the second argument char deviceAddress means)
        page_write(n / 256, ??, &memory[n], pageBytesToWrite);
    }


body:
[This tutorial][1] is from 2012, before the MKR1000 existed. The tutorial says the 16x32 LED Matrix panel is compatible with the Arduino Zero, which the MKR1000 is supposedly related to, so I'm thinking I should be able to upload the same program. However, the board keeps disconnecting every time I try to upload a simple sketch, so I am worried that perhaps they are not compatible. I am using the same wiring as the Arduino Uno (using pins 2-10, A0, A1, A2, GND on the MKR1000) that you can see in this tutorial

  [1]: https://learn.adafruit.com/32x16-32x32-rgb-led-matrix/connecting-with-jumper-wires

title: MKR1000 disconnecting when hooked up to RGB 16x32 LED Matrix

Answers: 0


body:
Im using an arduino uno and a sim 900, the simcard is setup and working as I can make a phone call to it and it rings.

The sim 900 is powered via the power jack and the uno is currently powered using USB.

I am trying to print out incoming text messages however with serial monitor open I only see "Initialising...".

        #include <SoftwareSerial.h>

    //Create software serial object to communicate with SIM900
    SoftwareSerial mySerial(7, 8); //SIM900 Tx & Rx is connected to Arduino #7 & #8

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

      //Begin serial communication with Arduino and SIM900
      mySerial.begin(9600);

      Serial.println("Initializing...");
      delay(1000);

      mySerial.println("AT"); //Handshaking with SIM900
      updateSerial();

      mySerial.println("AT+CMGF=1"); // Configuring TEXT mode
      updateSerial();
      mySerial.println("AT+CNMI=1,2,0,0,0"); // Decides how newly arrived SMS messages should be handled
      updateSerial();
    }

    void loop()
    {
      updateSerial();
    }

    void updateSerial()
    {
      delay(500);
      while (Serial.available())
      {
        mySerial.write(Serial.read());//Forward what Serial received to Software Serial Port
      }
      while(mySerial.available())
      {
        Serial.write(mySerial.read());//Forward what Software Serial received to Serial Port
      }
    }

[![enter image description here][1]][1]

  [1]: https://i.stack.imgur.com/QBZV9.jpg

I cant for the life of me figure out why its not printing anything else out? Can anyone give me any guidance or what to check?

title: Arduino Communication with Sim 900

Answers: 1

body:
The 'Initializing' printout happens because that is sent directly to the UNO's hardware serial port.  The rest doesn't happen because it is directed to the SIM card via SoftwareSerial pins 7 & 8, and the SIM card apparently isn't responding.

Cut the problem in half:  Connect pins 7 & 8 together, and run your program again.  If you get "AT" and the rest, then you know the 'MySerial' port is active and working correctly, and the problem is in the SIM 'half'.  Maybe you have an incorrect wire connection there, or maybe the SIM card's default serial rate isn't 9600, or something like that.  YMMV ;-).

As a test, I ran your program on a UNO, with a jumper wire between pins 7 & 8.  Unfortunately this did not work, but now I knew that the problem had nothing to do with the SIM shield. The result wasn't what I expected, but now I had 'cut the problem in half'.

Now that I had determined that the SIM card wasn't a factor (so far, anyway), I could concentrate on the 'UNO half'.  After some web research I found that 'Software Serial' doesn't support 'loopback' (looping the transmit line back into the receive line) because it cannot simultaneously transmit and receive.  Fortunately, the 'AltSoftSerial' library by Paul Stoffregen **does** support simultaneous transmit & receive, and so will support loopback.

So, I installed the library on my Arduino setup, and compiled and uploaded the example shown below.

<!-- language-all: lang-C++ -->

    #include <AltSoftSerial.h>

    // AltSoftSerial always uses these pins:
    //
    // Board          Transmit  Receive   PWM Unusable
    // -----          --------  -------   ------------
    // Teensy 3.0 & 3.1  21        20         22
    // Teensy 2.0         9        10       (none)
    // Teensy++ 2.0      25         4       26, 27
    // Arduino Uno        9         8         10
    // Arduino Leonardo   5        13       (none)
    // Arduino Mega      46        48       44, 45
    // Wiring-S           5         6          4
    // Sanguino          13        14         12

    AltSoftSerial altSerial;

    void setup() {
     Serial.begin(9600);
     //while (!Serial); // wait for Arduino Serial Monitor to open
     Serial.println("AltSoftSerial Test Begin");
     altSerial.begin(9600);
     altSerial.println("Hello World");
    }

    void loop() {
     char c;

     if (Serial.available()) {
      c = Serial.read();
      altSerial.print(c);
     }
     if (altSerial.available()) {
      c = altSerial.read();
      Serial.print(c);
     }
    }

After uploading the code, I 'looped' pin 9 back to pin 8, and found that when I sent characters to the UNO via the hardware USB port, they showed up again 'echoed' to the serial output after having traversed the AltSoftSerial port 8/9.

So at this point I have solved the UNO 'half' of the problem; the rest is up to you! ;-)


body:
I'm am completing a project of mine that uses an MCP3424 i2c 18bit ADC and an arduino nano to measure temperature with an NTC thermistor but am having trouble with the arduino wire library. This is my first project using i2c so I'm not very knowledgeable about the subject but I have rigorously read the datasheet of the MCP3424 that can be found at (http://ww1.microchip.com/downloads/en/devicedoc/22088b.pdf)
and tried many different ways to get it working. Also I'm new to posting on this stackexchange so pardon me if my syntax and what not is not right(I'm doing my best). Here is the code I have so far that is on my arduino.

```c
#include<Wire.h>

#define ReadMode 0xDD //Device will output conversion data (7 bits, device address. 1 bit, Read/Write mode)
#define WriteMode 0xDC //Device expects config byte (7 bits, device address. 1 bit, Read/Write mode)
#define ConfigByte18 0x8c //PGA = 1, SPS = 3.75, One-Shot mode, channel 1, initiate new conversion.
#define ConfigByte16 0x88 //PGA = 1, SPS = 15, One-Shot mode, channel 1, initiate new conversion.

void setup() {
  Serial.begin(9600);//Initiate Connection to computer
  Wire.begin();//Initiate Wire library
  Wire.setClock(100000);//make sure clock speed is standard mode
  delay(500);//Allow boot up and settle of ADC
  Wire.beginTransmission(WriteMode);//begin transmission with ADC in Write mode
  Wire.write(ConfigByte18);//configure the ADC with settings found in "ConfigByte18"
  Wire.endTransmission();
  Serial.print("Everything worked\n");

}

void loop() {
  unsigned char x, y, z, a, b, c;
  //Serial.println("Bytes ready to be read:");
  Wire.begin();
  Wire.setClock(100000);//make sure clock speed is standard mode
  Wire.beginTransmission(ReadMode);//begin transmission with ADC in write mode
  Wire.requestFrom(0x6E, 6);//request 6 Bytes of information from MCP3424
  x = Wire.read();//read bytes
  delay(10);
  y = Wire.read();
  delay(10);
  z = Wire.read();
  delay(10);
  a = Wire.read();
  delay(10);
  b = Wire.read();
  delay(10);
  c = Wire.read();
  Serial.print(x);//print bytes
  Serial.print(", ");
  Serial.print(y);
  Serial.print(", ");
  Serial.print(z);
  Serial.print(", ");
  Serial.print(a, HEX);
  Serial.print(", ");
  Serial.print(b, HEX);
  Serial.print(", ");
  Serial.println(c, HEX);
  Wire.endTransmission();
  delay(1000);

}
```

So an explanation of my understanding: In the “void setup” section I begin transmission in write mode (see page 21 of datasheet to follow along with my explanation figure and table 5-3) in the begin transmission function I address the slave with 0xDC because the device address begins with 1101 (pre programmed) and then 110 as I have the two Adr pins tied to +5v and finally 0 as I want to change configuration settings. This translates to 0xDC in hexadecimal. Then I send the slave a byte of information for the configuration register (see page 18 section 5.2). I send 0x8C as I want my settings to be PGA = 1, SPS = 3.75, One-Shot mode, channel 1, initiate new conversion. Which should mean I need to send the slave 10001100 or 0x8c. This communication then ends as “Any byte sent after this second byte will be ignored” according to page 21. Then in the loop I begin transmission the same way apart from now I open transmission in read mode which is 0xDD as the last bit (R/W bit) is now 1. I then request six bytes of information and read the six bytes. If you now go to page 23 of the datasheet you can follow along again. Here I should get three data bytes from the slave and every subsequent byte should be the configuration register settings repeated. For now I am uninterested in the first three data bytes as I first of all just want to know how to change the configuration settings. What gets printed by the arduino instead is three data bytes from the slave, as expected, and then three of the exact same value, also as expected as they should all be the configuration settings. What is being printed in the second three bytes is “90”. Not what I expected. Now I’ve tried to figure out what has happened (hard without an oscilloscope). 90 converted from hex to binary is 10010000 and I believe the default settings are (which can be found on page 18) 00001001 could this be the default settings if so can anyone tell me whats going on and how to fix it? Thank you in advance for the help and thank you for taking the time to read my problem.

title: Communication between arduino nano and MCP3424 over I2c

Answers: 1

body:
The problem is, that you misunderstood, how the `Wire` library handles addresses.

I2C uses an address byte, where the first 7 bits are the actual address and the last bit (Read/Write bit) dictates the direction of the communication. The `Wire` library gives you different functions for both directions (in your case: `Wire.beginTransmission()` for master write and `Wire.requestFrom()` for master read) and hides away the complexity of the Read/Write bit. So what you have to give as an address is the pure address of the device without the Read/Write bit. To write the configuration you used the address `0xDC`, but the actual address of the device is `0x6E` as you used it in the `Wire.requestFrom()` call.

Also in your `loop()` you try to start a master write with `Wire.beginTransmission()`, though you are starting a master read directly after it. `Wire.beginTransmission()` and `Wire.endTransmission()` are purely for master write transactions. So you should delete these lines here. For master read the call to `Wire.requestFrom()` and the corresponding reading is enough.

**What happens in your code:** In `setup()` you write the new configuration data to a wrong address (`0xDC` instead of `0x6E`). The transmission fails, as there is most likely no device with this address at the bus, but you don't notice, since you are not checking the return value of `Wire.endTransmission()`, which would show an error code. Then in the `loop()` function you reinitialize and reconfigure the whole `Wire` library again, which makes no sense, as Juraj mentioned in his comments. Though it will only cost some cycles of computation time. Then the library get's set to master write mode (no actual I2C action here, just interal to the library) and then to master read mode (actual I2C action. The provided number of bytes get's read here from the slave). At the end you say to the library, that is should finish the master write transmission from before, which is not there anymore (since you've done a master read). So this will do nothing. Also you are doing many delays between the reads, which is not necessary. When the `Wire.requestFrom()` function returns, all the I2C communication is finished. The bytes, that could be received, are received and written into the libraries buffer. `Wire.read()` will only read the next value from the buffer, remove it from there and return the value. No I2C action at that point, so the `delay(10)` is useless

TL;DR:

- Always use the correct address without Read/Write bit: `0x6E`
- Initialize and configure the `Wire` library only once in `setup()`
- Remove `Wire.beginTransmission()` and `Wire.endTransmission()` from the `loop()` function, as you are only doing master read there.
- Remove the `delay(10);` lines between the calls to `Wire.read()`


body:
I'm using an analog input on a NANO board to measure the midpoint between two photo resistive (Cadmium) cells, with the two outside ends tied to GND and a source voltage. Basically a simple voltage divider. So it almost wouldn't matter what reference voltage I used in a case like that, as long as the AnalogReference() was correctly set corresponding to the reference voltage, AND the load did not pull down that voltage.

Well if I used the 5V for my source, and set AnalogReference(DEFAULT), then assuming a worst case load of 4K-ohm, the total load on the 5V regulator is still only 1.25mA. But even so, I figured I could minimize the system load even more by setting AnalogReference(INTERNAL), and using the VREF pin as a source for my voltage divider.

Well it seems to work fine, but I don't know that I've seen any actual examples of what I'm doing, which is using the AREF pin as a source output voltage for my voltage divider. Using vREF as a source, a 4K load would only draw 27.5 microamps with a 1.1V source. But I can't find any spec for the max current I should avoid exceeding, That has me worried maybe I'm not even supposed to be doing that!

So is it acceptable to use the VREF pin as an output for light loads, when using the INTERNAL AnalogReference?

Thoughts?

EDIT: After receiving a "no" answer yesterday, I did some bench checking. I configured my NANO board for Internal, and connected a fully open 100K linear pot from AREF to Ground, with a DVM in parallel. The AREF terminal output was about 1.076, with or without the 100K load. Not quite the 1.1 specified but close enough. I then slowly rotated the pot to increase load. At just under 9K the voltage dropped a somewhat insignificant amount, to 1.075. From there on there were additional small decreases, down to about 1K, at which point i measured about 1.062V. Below 1K, there was a very steep decrease.

Note that this was a "quickie" test, done while powering the NANO from a USB port. However, repeating the test with 12V on the DV input did not alter the results significantly.

Even considering the USB source, from this test I conclude:

1) There does appear to be some buffering on the VREF output. It certainly did not behave as there was a simple case of a 1.1V source in series with a high impedance.

2) Up to a load of 10K, the VREF output seems at least as stable as the 5.0V regulator output.

3) Since a 1.062 drop from an initial no-load voltage of 1.076 equates to less than a 2% difference, I have to conclude that a load on VREF (to ground) greater than 1K (lets say 2K for margin) makes VREF probably useful in cases like i described, with a worst case load of 4K.

4) I repeated my test with a second NANO board. This time the initial no-load voltage was salightly higher, 1.084. However, the response to increasing load and the K point where the slope changed dramatically were unchanged.

Again, this is an arduino NANO board, and probably a clone. Can anyone else verify or disprove my results? I'm sure someone else will need to consider using VREF as I did, and it would be good to know.

title: Is AREF a stable output Ref voltage with analogReference(INTERNAL)

Answers: 2

body:
No, it is not acceptable.

The datasheet states:

> AVCC is connected to the ADC through a passive switch. The internal 1.1V reference is generated from the internal bandgap reference (VBG) through an internal amplifier. In either case, the external AREF pin is directly connected to the ADC, and the reference voltage can be made more immune to noise by connecting a capacitor between the AREF pin and ground. VREF can also be measured at the AREF pin with a high impedance voltmeter. **Note that VREF is a high impedance source, and only a capacitive load should be connected in a system.**

The 1.1V reference is *only* presented on the AREF pin for the purpose of adding an external bypass capacitor, or for measuring it using a very high impedance meter. Any load applied to the pin *will* cause the reference voltage to droop.

While it may work in certain circumstances it's certainly not recommended. If you want to use it externally you should buffer it through a high-impedance unity-gain voltage follower:

<!-- Begin schematic: In order to preserve an editable schematic, please
     don't edit this section directly.
     Click the "edit" link below the image in the preview instead. -->

![schematic](https://i.stack.imgur.com/uNjhI.png)

<!-- End schematic -->

body:
Now, having had the benefit of a support ticket and subsequent discussion with an engineer at TI on this subject, I can confidently offer a *qualified* YES to my own question. It turns out my case is probably the only one that would be within those qualifications.

 1. In the case where the RATIO between two hi-resistances is the ONLY thing needed from an A/D measurement, it is acceptable to use AREF and GND for the applied voltage, provided the load is low (see item 2). The main reason is that any droop in the AREF caused by the added load would not affect the ratio.
 2. The use of AREF for such a situation should still ensure limiting any load on the AREF pin to about 91uA. For the 1.1V (INTERNAL) source selection, that equates to about a 12K load. The number is based on a reverse calculation that would cause a 1 LSB difference in analog readings, *IF* other analog inputs are expected to be used for other non ratio-metric measurements.
 3.  Using the AREF pin this way makes it even more important to add a capacitor from the pin to GND.
 4. Apparently there is no danger of harming the chip in any way, should the AREF pin become shorted.

I will comment that the engineer responding to my support ticket understood I was trying to avoid a PCB change, but recommended a different approach if I had occasion to make other board changes anyway. His recommendation was to use the EXTERNAL Analog reference option, using the available 3.3V pin for AREF voltage, and using a digital output to supply my voltage divider. The idea here is that I would still have the benefit of short circuit protection, and since I was concerned about power saving, I could switch the Digital output pin to a low state until readings needed to be taken, observing sensible delay for settling time.

A good suggestion indeed, but my reason for answering my own question here is because under the constraints given, using AREF as described in my OP is acceptable, will not affect the ratio measurement, and could not harm the chip.


body:
as I checked on Arduino website, they mentioned all boards: UNO, Nano, Mini, Mega have maximum sample rate 10kHz for each analog pin. So my concern is:
1) is there any difference between sampling rate when reading a single analog pin and multiple analog pins? For example, if we read only 1 analog input, maximum sample rate can reach 10kHz. How about maximum sample rate when we want to read 6 analog inputs? Maximum sample rate will be 10kHz or (10/6)kHz? Can we do analog input reading simultaneously or not?

2) What if I want to get sampling rate at least 1kHz for each Arduino board (assume 5 analog inputs)?

3) In case we need to connect several Arduino boards via I2C or SPI protocol, is sampling rate related to these 2 protocols?

title: Sampling rate of multiple analog pins on Arduino

Answers: 1

body:
1)  You only have one ADC on board and all the pins run through a mux.  You can only read one pin at time.  If you're willing to give up some resolution then you might can read a little faster but it gets tough.  What's worse is that when you are switching pins really fast it can mess with your readings so that for some things, especially when input impedance is high, you have to read twice and throw away the first reading.  So that essentially cuts your sampling rate in half right there.

2)  That may be doable.  Or at least something close to it.  You'd run in free-running mode and write a tight ISR to read the interrupt when the analog read is finished and record every other value and switch the pin every other time.  Theoretically you should get pretty close to 1kHz with 5 pins.  Maybe a little faster if you give up a little resolution.

3)  Those communications protocols run at light speed compared to the analog read.