body:
This question is asked a lot and I've found many usable details on different forums regarding adding pull-up resistors on SDA/SCL lines. I know that only one resistor should be added on these lines regardless of how many devices are attached.

One thing that is not clear for me is that what if I2C devices are powered on from different sources, at different timing?
In following schematic, I have used pull up resistors for both I2C devices. Considering devices might be turned on and off at different timing, or even one device might be absent, is it fine to remove the second pull up resistors (second I2C device) and connect them directly to SDA/SCL pins on uC? In this case (removing pull-up resistors from second device), what happens if device 1 is not available and only second device is connected?

---edit:

- Schematic was updated to include only one pair of pull up resistors connected to master side.

- I will not how swap or hot plug I2C devices.

- I2C devices are sensors (BME280 [here][1], and Chirp capacitive soil moisture, [here][2]), not on breakout boards with preset pull up resistors.

- Is it possible to just connect resistors on master side and not slave side? In this case, would it be fine for both sensors?

<!-- 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/oetuB.png)

<!-- End schematic -->

  [1]: https://ae-bst.resource.bosch.com/media/_tech/media/datasheets/BST-BME280-DS002.pdf
  [2]: https://www.tindie.com/products/miceuz/i2c-soil-moisture-sensor/

title: Multiple I2C slave devices on Arduino - Pull-up values

Answers: 3

body:
I would include one resistor on each line at the master, powered by the master. That isn't the only option, just what I consider a cleaner simpler option.

The resistance is needed to provide the high seen on the line. The value of the resistance can vary. There is no one correct value. The pull up resistance needs to provide a high in the required time. There are specifications for this.

https://www.i2c-bus.org/specification/

If the lines do not have a lot of capacitance (wire and device capacitance) then a higher value resistance may be sufficient to meet the timing specification. If there is more capacitance then a lower resistance would be required to provide the stronger pull up in order to meet the timing requirements.

As far as multiple resistances. Yes there can be more than one on the line. But the accumulated resistance must be taken into account.

Many I2C devices mounted on a breakout board have pull up resistors. Typically these are around 5K Ohms. So if there are two devices, each with their own resistors, the combined total will still be within the lowest resistance that would be acceptable.

One thing to note. The specification does not list a lowest resistance that can be used. Instead it specifies the minimum sinking requirement of a device that would need to pull the voltage low enough. So a current is specified, and this current can be used to calculate the minimum resistance on the line.

The current spec (somewhere about 3ma I think, or maybe 2ma??) would calculate to being a 1k6 resistance when used with a 5 volt supply. With a 3.3 volt supply the calculated value would be about 1k1 Ohms. (again, this is a rough calculation, close enough for handgrenades)

This is enough of an answer considering what was asked. There are different modes/speeds and different combinations that can be applied and things can get very involved. And then you must spend the time and look at the specifications. But for most Arduino work this rough guide should cover most "normal" situations.

It really is quite an interesting technology.

body:
You should consider adding some bus isolation between each slave and the master. The reason being is that the ESD diodes in the SCL/SDA pins of a slave that is powered down could be interfering with the I2C bus as they leech power from the bus to feed through the internals of the slave.  Given the low current imposed by the pullup resistors being the only power source this shouldn't cause any damage to the slave, but it may well cause the I2C bus to be seen as LOW when it shouldn't, causing communication to fail.

You should add a buffer with an "enable" pin of its own between each slave and the bus.  My device of choice is the [PCA9306](http://www.ti.com/product/PCA9306) from Texas Instruments.  It also means that the slave has its own separate pullup resistors powered by its own 3.3V rail, keeping all the power separate.

You would then have sequences such as:

1. Power up slave
2. Give short powerup delay (if needed)
3. Enable PCA9306
4. Do I2C transactions
5. Disable PCA9306
6. Power off slave

The PCA9306 can also be used to connect 3.3V slaves to a 5V MCU if needed.

<!-- 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/hkDtE.png)

<!-- End schematic -->

body:
I wanted to add this as a comment but I ran out of characters, so this isn't an answer, just more comment.

    @Majenko "I would never suggest using I2C over anything other than short PCB traces. i2C + wires = no thank you sir."

And that made me write the following.

We had one product that needed an external radio module. I put a connector in to extend the I2C bus. Total length of the additional cable was about 4 feet. Enough to route it outside the box and mount the radio close by.

Much later I am asked to look at why the communications is failing. The engineering manager had the cable extended to 20 feet. It worked for him *on the bench* when he tested it. No scope check on waveforms. No calculations. (he was a firmware programmer with just enough hardware knowledge to do his job)

I looked at the waveforms with a scope and I was shocked that it worked at all. The I2C lines were cpu to cpu. The radio had a microcontroller that acted as a slave I2C device.

I put a couple of buffers on either end and all was back in spec and it worked reliably after that, in the field and not just on the bench.

We have a bigger control box that uses I2C to communicate to modules in the back of the box. I have a buffer at the CPU end. The cpu is 3.3v, the modules are 5 volts. The buffer does a level conversion and stronger drive than the cpu could handle. The back of the boxes are shown below. Space for 14 modules. The bigger box is about 2 feet wide and 3 feet tall. The I2C lines run vertically down the center of each of the columns on the back of the board.

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

There also can be a secondary slave box for an additional 14 modules. The same back board. I used a second I2C port with and isolated I2C buffer for driving the lines. The slave boax was to be mounted beside the main box. Again I specified a short cable, this time six feet in length.

So one day I am asked if the cable can be extended. The contractor installing the panels wanted to put the slave boax on the other side of the hall by another electrical panel. I ask how long do they need. I'm told it is ten feet away. Yeah, ten feet line of sight. Once the cable was touted up into the ceiling, across the hall, and then down to the other box, the 10 feet turned into 30 feet.

I did a check with a scope. The rise times were still in spec, it seemed to work, so we made up a cable and told them that it may or may not work. Use at their own risk. I told them this was an exception and it is not to be a part of the product offering. But I'm sure there will be more exceptions.

And while it can work over those kind of distances the following shows how I2C can fail over short distances.

Same equipment. The smaller box in the picture was expanded with an additional larger box. The smaller box was mounted eight inches above the bigger box. (display and main cpu in the front panel of the product) Only temperature input into the modules in the smaller box. The bigger box was loaded with modules with control relays. Four 17 amp relays per module.  Same electronics as in the exception described above. But they were having lots of sporadic behaviour. Pictures of the wiring, the installation, looked clean and well done. I had no idea why it was failing.

After this had been going on for a couple of months I asked our customer service person to ask what they have connected to our relays. Normally it would be motor up to 1 hp. They were controlling bigger motors and they had our relays turning on power contactors in a different panel. Lots of power contactors. All generating voltage spikes when they were turned off. I had them put snubbers across the contactor coils and the problems went away.

So I2C can work over longer distances, and it can fail over shorter distances. The whole picture needs to be taken into account. The problem is the whole picture often is hard to see.

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


body:
I bought a Feather M0 Basic from a reseller [Lawicel][1] however I'm missing the
UF2 boot feature. When I press the reset button two times I just
get a serial and have to program circuitpython using Bossa. The ```UF2```
```FEATHERBOOT``` usb storage drive as described  [here][2] doesnt show up.

I have a ARM-ICE and wired up the Feather board via SWD. I
can re-program the bootloader (first setting fuse to NVMCTRL_BOOTPROT 0x7
as described [here][3] ) via ARM-ICE.

However it seems that the Arduino bootloader [featherm0bootloader_160305.zip][4] is an old one that doesnt support the UF2 usb storage device programming protocol.

Where can I download a more recent bootloader that supports UF2 ?

  [1]: https://www.lawicel-shop.se/
  [2]: https://learn.adafruit.com/welcome-to-circuitpython/installing-circuitpython
  [3]: https://learn.adafruit.com/proper-step-debugging-atsamd21-arduino-zero-m0/restoring-bootloader
  [4]: https://learn.adafruit.com/system/assets/assets/000/031/337/original/featherm0bootloader_160305.zip?1458155274

title: Adafruit Feather M0 Basic update bootloader

Answers: 0


body:
I hope you all well.

Recently after view unknown crashes I decided it can be related with me messing with "heap"

After reading few sources on heaps and how it works it kind of confusing. Some sources mention that you can F() everything and it will be fine and others mention reserving space for strings with "reserve()"

I am looking for suggestions how possibly eliminate or or control?

I will post snapshot of code below where the evil "String" is used few times.

    ////////sending data
        senddata(String(temp), String(hum), String(dis), String(flood), String(heaterstatus), String(humidifierstatus));
        //////////sending data

    void senddata(String temp1, String hum1, String dis1, String flood1, String heater1, String humid1) {   /////sending all field values in one go
      //////////sending data
      String getData = "GET /update?api_key=" + API + "&field1=" + temp1 + "&field2=" + hum1 + "&field3=" + dis1 + "&field4=" + flood1 + "&field5=" + heater1 + "&field6=" + humid1;
      sendCommand("AT+CIPMUX=1", 5, "OK");
      sendCommand("AT+CIPSTART=0,\"TCP\",\"" + HOST + "\"," + PORT, 15, "OK");
      sendCommand("AT+CIPSEND=0," + String(getData.length() + 4), 4, ">");
      esp8266.println(getData); delay(1500); countTrueCommand++;
      sendCommand("AT+CIPCLOSE=0", 5, "OK");
    }

title: String and heap confusion

Answers: 1

body:
Yes, you could make a global String for `getData` and reserve space and reuse it every time the function is called. But what with `String(getData.length())`?

And the parameters? You create a new String for every parameter. And the function `senddata` doesn't take a reference to the String (String&), but it makes a new copy of each String parameter. So you create 12 small Strings with every call to this function. This is the evil of String. It does everything no matter at what cost.

And your sendCommand takes String too. That is why you can do `"AT+CIPSTART=0,\"TCP\",\"" + HOST + "\"," + PORT` and `"AT+CIPSEND=0," + String(getData.length() + 4)` as parameter to it. So every call to sendCommand creates two small Strings. That is 8. And every `+` on String can trigger a reallocation on heap.

Use C strings

    void senddata(int temp1, int hum1, int dis1, int flood1, int heater1, int humid1) {
      char getData[256];
      snprintf(getData, sizeof(getData), "GET /update?api_key=%s&field1=%d&field2=%d&field3=%d&field4=%s&field5=%s&field6=%d",
          API, temp1, hum1, dis1, flood1, heater1, humid1);
      sendCommand("AT+CIPMUX=1", 5, "OK");
      char buff[32];
      snprintf(buff, sizeof(buff), "AT+CIPSTART=0,\"TCP\",\"%s\",%d" , HOST, PORT);
      sendCommand(buff, 15, "OK");
      snprintf(buff, sizeof(buff), "AT+CIPSEND=0,%d" , strlen(getData) + 4);
      sendCommand(buff, 4, ">");
    }

    void sendCommand(const char* command, const int timeout, const char* find) {

F macro optimizes memory use, by using data stored in flash memory. The snprintf_P function is a version of snprintf for format string from flash.

    snprintf_P(getData, sizeof(getData), (const char*) F("GET /update?api_key=%s&field1=%d&field2=%d&field3=%d&field4=%s&field5=%s&field6=%d"),
      API, temp1, hum1, dis1, flood1, heater1, humid1);

One of the classes of my StreamLib is CStringBuilder. With it the code could be:

    char getData[256];
    CStringBuilder sb(getData, sizeof(getData));
    sb.printf(F("GET /update?api_key=%s&field1=%d&field2=%d&field3=%d&field4=%s&field5=%s&field6=%d"),
        API, temp1, hum1, dis1, flood1, heater1, humid1);
    sendCommand("AT+CIPMUX=1", 5, "OK");
    char buff[32];
    CStringBuilder sb2(buff, sizeof(buff));
    sb2.printf(F("AT+CIPSTART=0,\"TCP\",\"%s\",%d") , HOST, PORT);
    sendCommand(buff, 15, "OK");
    sb2.reset();
    sb2.print(F("AT+CIPSEND=0,"));
    sb2.print(sb.length() + 4);
    sendCommand(buff, 4, ">");


body:
I am attempting to send data from an MPU6050 connected to an arduino uno to another uno via CAN bus, however i don't think this is a CAN bus specific issue.

In short, i am sending two packets of 8 bytes in the following formats

    Packet 1 - (uint32_t/ int16_t/ int16_t)
    Packet 2 - (int16_t/ int16_t/ int16_t/ int16_t)

all converted into bytes in this sort of fashion;

    int16_t byte2Int(int16_t output, int pos, uint8_t data[2]){
          for (int i = 0; i < 2; i++)
        {
          output += ((int16_t)data[i + pos]) << (i * 8);
        }
        return output;
    }

where everything should make sense apart from the "int pos" part which is just where in the buffer i want to start putting the data as packet 1 and 2 are different structures.

My issue is that with just one packet, i can print the values just fine, with the second packet added in i get the following on the serial monitor;

    AccX    AccY    AccZ  GyX    GyY     GyZ

    16832 -816 928 -440 16832 -816
    16984 -940 992 -449 16984 -940
    16896 -804 988 -462 16896 -804
    209 55 0 0 209 55
    16900 -852 1080 -471 16900 -852
    16900 -852 1080 -471 16900 -852
    16984 -760 948 -481 16984 -760
    16880 -824 896 -459 16880 -824
    230 102 0 0 230 102
    16928 -860 996 -422 16928 -860
    16928 -860 996 -422 16928 -860
    17004 -856 864 -466 17004 -856
    17004 -856 864 -466 17004 -856
    214 105 0 0 214 105
    16964 -828 944 -446 16964 -828
    16964 -828 944 -446 16964 -828

As you can see i get some coherent messages, then some scrambled which don't make sense, then coherent again and the cycle continues. Not sure of relevance, but when i first start the serial monitor this doesn't happen, then after varying time, but around 5 seconds or so, it starts going amiss.

I believe this is down to my programming, and me not being able to code in a reliable way to wait for the first message to complete, then send the next one and them being read correctly. Below is my embarrassing attempt at sending an ACK message to the sender to say that the message has been received and to progress to the next message. I am not a programmer by nature and i am putting up this shoddy code that i've spent days trying to sort in the hope someone can point me in the right direction.

Apologies in advance.

    // CAN Send Example
    //

    #include <mcp_can.h>
    #include <SPI.h>
    #include <Wire.h>

    const int MPU_addr = 0x68; // I2C address of the MPU-6050
    uint32_t TimeMicro;
    int16_t AccX, AccY, AccZ, Tmp, GyX, GyY, GyZ;
    int8_t data1[8], data2[8], rxBuf[8];
    int Switch = 7;
    long unsigned int rxId;
    unsigned char len = 0;

    #define CAN0_INT 2                              // Set INT to pin 2
    MCP_CAN CAN0(10);     // Set CS to pin 10

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

      // Initialize MCP2515 running at 16MHz with a baudrate of 500kb/s and the masks and filters disabled.
      if(CAN0.begin(MCP_ANY, CAN_500KBPS, MCP_16MHZ) == CAN_OK) Serial.println("MCP2515 Initialized Successfully!");
      else Serial.println("Error Initializing MCP2515...");

      CAN0.setMode(MCP_NORMAL);   // Change to normal mode to allow messages to be transmitted

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

      Wire.begin();
      Wire.beginTransmission(MPU_addr);
      Wire.write(0x6B);  // PWR_MGMT_1 register
      Wire.write(0);     // set to zero (wakes up the MPU-6050)
      Wire.endTransmission(true);

    }

    void loop()
    {

      TimeMicro = millis();

      Wire.beginTransmission(MPU_addr);
      Wire.write(0x3B);  // starting with register 0x3B (ACCEL_XOUT_H)
      Wire.endTransmission(false);
      Wire.requestFrom(MPU_addr, 14, true); // request a total of 14 registers
      AccX = Wire.read() << 8 | Wire.read(); // 0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L)
      AccY = Wire.read() << 8 | Wire.read(); // 0x3D (ACCEL_YOUT_H) & 0x3E (ACCEL_YOUT_L)
      AccZ = Wire.read() << 8 | Wire.read(); // 0x3F (ACCEL_ZOUT_H) & 0x40 (ACCEL_ZOUT_L)
      Tmp = Wire.read() << 8 | Wire.read();
      GyX = Wire.read() << 8 | Wire.read(); // 0x43 (GYRO_XOUT_H) & 0x44 (GYRO_XOUT_L)
      GyY = Wire.read() << 8 | Wire.read(); // 0x45 (GYRO_YOUT_H) & 0x46 (GYRO_YOUT_L)
      GyZ = Wire.read() << 8 | Wire.read(); // 0x47 (GYRO_ZOUT_H) & 0x48 (GYRO_ZOUT_L)

      double2Byte(TimeMicro, 0, data1);
      int2Byte(AccX, 4, data1);
      int2Byte(AccY, 6, data1);

      int2Byte(AccZ, 0, data2);
      int2Byte(GyX, 2, data2);
      int2Byte(GyY, 4, data2);
      int2Byte(GyZ, 6, data2);

      // send data:  ID = 0x100, Standard CAN Frame, Data length = 8 bytes, 'data' = array of data bytes to send
      byte sndStat = CAN0.sendMsgBuf(0x100, 0, 8, data1);

      if(!digitalRead(CAN0_INT))                         // If CAN0_INT pin is low, read receive buffer
      {
        CAN0.readMsgBuf(&rxId, &len, rxBuf);      // Read data: len = data length, buf = data byte(s)

        while(rxBuf[0] != 0x0A)
        {
          continue;
        }

      }
      delay(10);
      byte sndStat2 = CAN0.sendMsgBuf(0x100, 0, 8, data2);

        while(rxBuf[0] != 0x0A)
        {
          continue;
        }

      for(int i = 0; i < 8; i++)
      {
        data1[i] = 0;
        data2[i] = 0;
      }

    }

    //===================================================================================
    //                                  FUNCTIONS
    //===================================================================================
    uint8_t int2Byte(int16_t input, int pos, uint8_t data[2]){
      for (int i = 0; i < 2; i++)
      {
        data[i+ pos] = ((input >> (i * 8)) & 0xff);
      }
    return data[2];
    }

    uint8_t double2Byte(uint32_t input, int pos, uint8_t data[4]){
      for (int i = 0; i < 4; i++)
      {
        data[i+ pos] = ((input >> (i * 8)) & 0xff);
      }
    return data[4];
    }

    /*********************************************************************************************************
      END FILE
    *********************************************************************************************************/

Receiver

    // CAN Receive Example
    //

    #include <mcp_can.h>
    #include <SPI.h>

    long unsigned int rxId;
    unsigned char len = 0;
    unsigned char rxBuf1[8];
    unsigned char rxBuf2[8];
    unsigned char txBuf[8];
    char msgString[128];                        // Array to store serial string
    uint32_t TimeMicro;
    int16_t AccX, AccY, AccZ, GyX, GyY, GyZ;

    #define CAN0_INT 2                              // Set INT to pin 2
    MCP_CAN CAN0(10);                               // Set CS to pin 10

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

      // Initialize MCP2515 running at 16MHz with a baudrate of 500kb/s and the masks and filters disabled.
      if(CAN0.begin(MCP_ANY, CAN_500KBPS, MCP_16MHZ) == CAN_OK)
        Serial.println("MCP2515 Initialized Successfully!");
      else
        Serial.println("Error Initializing MCP2515...");

      CAN0.setMode(MCP_NORMAL);                     // Set operation mode to normal so the MCP2515 sends acks to received data.

      pinMode(CAN0_INT, INPUT);                            // Configuring pin for /INT input

      Serial.println("MCP2515 Library Receive Example...");
    }

    void loop()
    {
      if(!digitalRead(CAN0_INT))                         // If CAN0_INT pin is low, read receive buffer
      {
        CAN0.readMsgBuf(&rxId, &len, rxBuf1);      // Read data: len = data length, buf = data byte(s)
      }

      for(int i; i < 8; i++){
        txBuf[i] = 0x0A;
      }

      byte sndStat = CAN0.sendMsgBuf(0x101, 0, 8, txBuf);

      if(!digitalRead(CAN0_INT))                         // If CAN0_INT pin is low, read receive buffer
      {
      CAN0.readMsgBuf(&rxId, &len, rxBuf1);      // Read data: len = data length, buf = data byte(s)
      }

      byte sndStat2 = CAN0.sendMsgBuf(0x101, 0, 8, txBuf);

      TimeMicro = byte2Double(TimeMicro, 0, rxBuf1);
      AccX = byte2Int(AccX, 4, rxBuf1);
      AccY = byte2Int(AccY, 6, rxBuf1);
      AccZ = byte2Int(AccZ, 0, rxBuf2);
      GyX = byte2Int(GyX, 2, rxBuf2);
      GyY = byte2Int(GyY, 4, rxBuf2);
      GyZ = byte2Int(GyZ, 6, rxBuf2);

      Serial.print(TimeMicro);
      Serial.print("\t");
      Serial.print(AccX);
      Serial.print("\t");
      Serial.print(AccY);
      Serial.print("\t");
      Serial.print(AccZ);
      Serial.print("\t");
      Serial.print(GyX);
      Serial.print("\t");
      Serial.print(GyY);
      Serial.print("\t");
      Serial.println(GyZ);

      TimeMicro = 0;
      AccX = 0;
      AccY = 0;
      AccZ = 0;
      GyX = 0;
      GyY = 0;
      GyZ = 0;

    }

    //===================================================================================
    //                                  FUNCTIONS
    //===================================================================================

    uint32_t byte2Double(uint32_t output, int pos, uint8_t data[4]){
          for (int i = 0; i < 4; i++)
        {
          output += ((uint32_t)rxBuf1[i + pos]) << (i * 8);
        }
        return output;
    }

    int16_t byte2Int(int16_t output, int pos, uint8_t data[2]){
          for (int i = 0; i < 2; i++)
        {
          output += ((int16_t)rxBuf1[i + pos]) << (i * 8);
        }
        return output;
    }
    /*********************************************************************************************************
      END FILE
    *********************************************************************************************************/

I've tried debugging this by the following;

 - check that the MPU is sending correctly (Fine)
 - check if it happens with just one packet (no problems)
 - check if the packets are assembled correctly on the sender ( got the data,
    broke it into bytes and reassembled and printed that result. did what i
    expected)
 - removed time from being sent incase that was causing an issue (same problem
   as illustrated above)
 - removed all serial prints and just did one value (still an issue)

So i believe that it is down to a terrible and non working attempt at sending an acknowledgment message. I have tried researching but i couldn't find an example for CAN bus, and all the others were using protocol specific interrupt routines which i tried to implement but didn't work. obviously.

Thankyou for your patience

title: What could cause data to be printed correctly, then incorrectly and then repeated? CAN bus / general transmission

Answers: 2

body:
DISCLAIMER: Ok, I never worked with CAN on arduino, so I may be terribly wrong, nor I have the required boards to test this, so I may make a lot of errors; if you find any issue, please point them out, so I can fix them (or if you fixed them notify me, so I can update the reply for the future readers).

Ok, from what I can read you are have two packets, but only one CAN frame. This seems to me a huge inefficiency, because how can you know which frame have you just received?

To fix this, you can either use two frames or use something in the payload that informs you which frame you have received. In my opinion, since there are a lot of free IDs, you can use the first approach.

Moreover you are performing some checks in the processing (e.g. "did I receive an ack?"),  but if this fails you go on without further checking. For instance, when in the sender you write:

    byte sndStat = CAN0.sendMsgBuf(0x100, 0, 8, data1);
    if(!digitalRead(CAN0_INT))
    {
      ...
    }
    delay(10);
    byte sndStat2 = CAN0.sendMsgBuf(0x100, 0, 8, data2);

what happens when CAN0_INT is still high? Yes, it sends the data immediately.

I could not understand the `while(rxBuf[0] != 0x0A)` part; it will block your program forever...

Finally when you receive a message you never check the ID; this means you will check all the messages on CAN, and when you add another device on the net you will not be able to send any other message.

Ok, so this is what I'd try for your needs:

 - The TX board will always transmit data, while the RX board will always receive it. No ack frames is needed
 - There will be two frames on the network: frame 0x100 will have packet 1, while frame 0x101 will have packet 2
 - The TX board will send one message every 100ms; this can be reduced, but specify a time rather than having the part send frames "continuously"
 - The RX board will consider the data valid only after a 0x101 packet is received and a 0x100 packet was received before.

So, here is the code. Please note that I refactored some parts for easier understanding (putting some code in functions to have a smaller "higher level" setup and loop functions.

BTW what is the "Switch" in the sender? It is never used...

Sender:

    // CAN Send Example
    //

    #include <mcp_can.h>
    #include <SPI.h>
    #include <Wire.h>

    const int MPU_addr = 0x68; // I2C address of the MPU-6050

    uint32_t lastTimeSent;
    uint32_t currMillis;
    const uint32_t intervalSendMs = 100; // Send period in milliseconds

    int16_t AccX, AccY, AccZ, Tmp, GyX, GyY, GyZ;
    uint8_t data1[8], data2[8];
    int Switch = 7;

    #define CAN0_INT 2    // Set INT to pin 2
    MCP_CAN CAN0(10);     // Set CS to pin 10

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

     initializeMCP2515();

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

     initializeMPU6050();
    }

    void loop()
    {
     currMillis = millis();

     if ((currMillis - lastTimeSent) >= intervalSendMs)
     {
      lastTimeSent += intervalSendMs;

      readFromMPU6050();

      convertDataToPackets();

      // Send the two frames; if the first sending is successful send also the second, otherwise abort
      // send data frame 1:  ID = 0x100, Standard CAN Frame, Data length = 8 bytes, 'data' = array of data bytes to send
      // send data frame 2:  ID = 0x101, Standard CAN Frame, Data length = 8 bytes, 'data' = array of data bytes to send
      if (CAN0.sendMsgBuf(0x100, 0, 8, data1) == CAN_OK)
       CAN0.sendMsgBuf(0x101, 0, 8, data2);
     }
    }

    //===================================================================================
    //                                  FUNCTIONS
    //===================================================================================
    void initializeMCP2515()
    {
     // Initialize MCP2515 running at 16MHz with a baudrate of 500kb/s and the masks and filters disabled.
     if(CAN0.begin(MCP_ANY, CAN_500KBPS, MCP_16MHZ) == CAN_OK)
      Serial.println("MCP2515 Initialized Successfully!");
     else
      Serial.println("Error Initializing MCP2515...");

     CAN0.setMode(MCP_NORMAL);   // Change to normal mode to allow messages to be transmitted
    }

    void initializeMPU6050()
    {
     Wire.begin();
     Wire.beginTransmission(MPU_addr);
     Wire.write(0x6B);  // PWR_MGMT_1 register
     Wire.write(0);     // set to zero (wakes up the MPU-6050)
     Wire.endTransmission(true);
    }

    void readFromMPU6050()
    {
     Wire.beginTransmission(MPU_addr);
     Wire.write(0x3B);  // starting with register 0x3B (ACCEL_XOUT_H)
     Wire.endTransmission(false);
     Wire.requestFrom(MPU_addr, 14, true); // request a total of 14 registers
     AccX = Wire.read() << 8 | Wire.read(); // 0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L)
     AccY = Wire.read() << 8 | Wire.read(); // 0x3D (ACCEL_YOUT_H) & 0x3E (ACCEL_YOUT_L)
     AccZ = Wire.read() << 8 | Wire.read(); // 0x3F (ACCEL_ZOUT_H) & 0x40 (ACCEL_ZOUT_L)
     Tmp = Wire.read() << 8 | Wire.read();
     GyX = Wire.read() << 8 | Wire.read(); // 0x43 (GYRO_XOUT_H) & 0x44 (GYRO_XOUT_L)
     GyY = Wire.read() << 8 | Wire.read(); // 0x45 (GYRO_YOUT_H) & 0x46 (GYRO_YOUT_L)
     GyZ = Wire.read() << 8 | Wire.read(); // 0x47 (GYRO_ZOUT_H) & 0x48 (GYRO_ZOUT_L)
    }

    void convertDataToPackets()
    {
     long2Byte(currMillis, 0, data1);
     int2Byte(AccX, 4, data1);
     int2Byte(AccY, 6, data1);

     int2Byte(AccZ, 0, data2);
     int2Byte(GyX, 2, data2);
     int2Byte(GyY, 4, data2);
     int2Byte(GyZ, 6, data2);
    }

    void int2Byte(int16_t input, int pos, uint8_t *data)
    {
     for (int i = 0; i < 2; i++)
     {
      data[i + pos] = ((input >> (i * 8)) & 0xff);
     }
    }

    void long2Byte(uint32_t input, int pos, uint8_t *data)
    {
     for (int i = 0; i < 4; i++)
     {
      data[i + pos] = ((input >> (i * 8)) & 0xff);
     }
    }

    /*********************************************************************************************************
      END FILE
    *********************************************************************************************************/

Receiver:

    // CAN Receive Example
    //

    #include <mcp_can.h>
    #include <SPI.h>

    long unsigned int rxId;
    unsigned char len = 0;
    unsigned char rxBuf[8];
    uint8_t receivedFirstFrame;

    char msgString[128];                        // Array to store serial string
    uint32_t TimeMicro;
    int16_t AccX, AccY, AccZ, GyX, GyY, GyZ;

    #define CAN0_INT 2 // Set INT to pin 2
    MCP_CAN CAN0(10); // Set CS to pin 10

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

     initializeMCP2515();

     Serial.println("MCP2515 Library Receive Example...");
     receivedFirstFrame = 0;
    }

    void loop()
    {
     if(!digitalRead(CAN0_INT))
     {
      // Received a message
      if (CAN0.readMsgBuf(&rxId, &len, rxBuf) == CAN_OK)
      {
       // Note: the above line is not like in the examples, but looking at the code the
       // function may return if no message was in the queue, so I think this is safer

       // Let's check if it is one of the known messages
       switch (rxId)
       {
       case 0x100:
        { // Received first frame
         // Decode the content and store that the first frame was received
         decodeFirstFrame(rxBuf);
         receivedFirstFrame = 1;
        }
        break;
       case 0x101:
        if (receivedFirstFrame)
        { // Received second frame after a first frame
         // Decode the content
         decodeSecondFrame(rxBuf);

         printDataToSerial();

         receivedFirstFrame = 0;
        }
        break;
       }
      }
     }
    }

    //===================================================================================
    //                                  FUNCTIONS
    //===================================================================================

    void initializeMCP2515()
    {
     // Initialize MCP2515 running at 16MHz with a baudrate of 500kb/s and the masks and filters disabled.
     if(CAN0.begin(MCP_ANY, CAN_500KBPS, MCP_16MHZ) == CAN_OK)
      Serial.println("MCP2515 Initialized Successfully!");
     else
      Serial.println("Error Initializing MCP2515...");

     CAN0.setMode(MCP_NORMAL); // Change to normal mode to allow messages to be transmitted

     pinMode(CAN0_INT, INPUT); // Configuring pin for /INT input
    }

    void decodeFirstFrame(uint8_t *buffer)
    {
     TimeMicro = byte2Double(0, buffer);
     AccX = byte2Int(4, buffer);
     AccY = byte2Int(6, buffer);
    }

    void decodeSecondFrame(uint8_t *buffer)
    {
     AccZ = byte2Int(0, buffer);
     GyX = byte2Int(2, buffer);
     GyY = byte2Int(4, buffer);
     GyZ = byte2Int(6, buffer);
    }

    void printDataToSerial()
    {
     Serial.print(TimeMicro);
     Serial.print("\t");
     Serial.print(AccX);
     Serial.print("\t");
     Serial.print(AccY);
     Serial.print("\t");
     Serial.print(AccZ);
     Serial.print("\t");
     Serial.print(GyX);
     Serial.print("\t");
     Serial.print(GyY);
     Serial.print("\t");
     Serial.println(GyZ);
    }

    uint32_t byte2Double(int pos, uint8_t *data)
    {
        uint32_t output = 0;
        for (int i = 0; i < 4; i++)
        {
          output += ((uint32_t)data[i + pos]) << (i * 8);
        }
        return output;
    }

    int16_t byte2Int(int pos, uint8_t *data)
    {
        int16_t output = 0;
        for (int i = 0; i < 2; i++)
        {
          output += ((int16_t)data[i + pos]) << (i * 8);
        }
        return output;
    }
    /*********************************************************************************************************
      END FILE
    *********************************************************************************************************/

Please let me know if you have any comments or find some issues with this.

body:
There are indeed a few coding issues in your sketch, especially in the receiver part. I will try to list them and suggest changes.

 1. If you look closely to your received data, you will see that `AccX==GyY` and `AccY==GyZ` on every line of your output. This is because you use the global variable `rxBuf1` in your `byte2Int` and `byte2Double` functions on the receiver side. This causes the output to consume `rxBuf1` also for the second CAN frame. Instead you should use the pointer to `data` that you have prepared in the inputs for this purpose.
 2. In the receiver sketch, for both times you read in the CAN message with  `CAN0.readMsgBuf` you write the result to `rxBuf1`, although for the second read you most likely intended to write to `rxBuf2`. Now you simply overwrite `rxBuf1` and therefore the content of the first received CAN message in the loop is never evaluated.
 3. The switched outputs every few lines, in my opinion, are most likely due to a mixed order of both messages on the receiver side, when you receive CAN message 2 before CAN message 1. In order to avoid this, please follow the nice suggestions by @frarugi87 to send both messages with separate CAN IDs and to check for receiption of both before printing them.
 4. I also agree that you can get rid of the acknowledge reply from the receiver. The can protocol already contains an acknowledge mechanism on the CAN transceiver that will notify the sender that at least one listening node has correctly received the message. If the sender does not get this [acknowledge indication][1], it will repeat to send the message for some time.

  [1]: https://www.kvaser.com/about-can/the-can-protocol/can-error-handling/


body:
I have an Arduino Micro connected to two I2C devices. An MPU-6050 that is powered by 5V (though it has its own voltage regulator on it) and a Altimeter that is powered by 3.3V. They are both connected to the SDA and SCL.

I noticed that when I have the MPU powered on but don't power the 3.3V altimeter, the MPU does not communicate with the Arduino. I need to have the 3.3V power on to just communicate with the MPU through I2C. Why does this happen?

Then unfortunately, I believe I may have shorted the 3.3V rail and broke the altimeter. When I remove the MPU from the equation and try to just communicate with the Altimeter, I get nothing. Does this mean that I did short the device, or is there something else going on with I2C that I don't understand?

I have attached a schematic below of how the devices are connected.

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

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

title: Bad Communication with Multiple I2C Devices

Answers: 2

body:
>  I would like to know why when one device is bad (or not powered) on
> I2C, it screws up the other devices.

The I2C lines need to have a pull up resistor to provide the high. The master device, and the slave devices, ground the line to provide a low, but they release the line, and not drive it at all, in order to provide the high.

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

Consider switches a and b to be inside the I2C device. When the switch a is open point A will be at 5 volts. When switch a is closed, point A will be at 0 volts.

Now if you had a second set of R resistors on the same line, but powered from their own 5 volt power supply, the same voltages will be seen at A when switch a is open (5 volts) and switch a is closed (0 volts).

But now if we kill the supply feeding the second set of R resistors (sorry that I can't show them in a picture) instead of pulling up to 5 volts (because we killed the 5 volts) the resistors will be pulling down due to whatever other loads there are on the killed 5 volt supply. And just for argument sake, let's say the killed 5 volt supply was at 0 volts.

So if one set of resistors is pulling up to 5 volts (the still powered pair) and one pulling down (the killed pair) then the voltage at points A and B will not be as high as the 5 volts we would see when the switches are open.  If all the resistors R were the same value, and the killed supply was at 0 volts, then the highest voltage at A or B would be 2.5 volts. And that is not a good high.

So the additional device, that is not being powered, has disrupted the communitations, preventing true highs. Lows are not affected as the switch will pull the line low.

I don't know the values of all your pull up resistors, and don't know how low the dead supply goes, so I can't say what the new lower highest voltage is. But it seems that it is low enough to make the communications stop working.

And the resistor are not the only thing that can be disgusting the high. The unpowered chip can be providing unexpected current paths. Most port pins have an internal diode to Vcc. And since the chip has no power on Vcc the current on the I2C lines can follow that path to ground.

Also, I think you have drawn the resistors wrong. If they were in series with the SDA and the SCL pins there would be no communications because the 1k resistors doesn't allow the SDA line to be pulled low enough. I think those resistors are pull up resistors. Maybe you can take another look and confirm the connection.

  [1]: https://i.stack.imgur.com/iECva.gif

body:
When a device is unpowered any voltage placed on an IO pin is leeched off and fed to the VCC pin through the internal ESD protection diodes.  On a bus like I2C this then cripples the bus. (Note: even if there are no intentional protection diodes the MOSFETs that drive the lines have diodes built into them and these act as protection diodes, but they are very weak and can be easily broken).

**You cannot have an unpowered device on an I2C bus** and doing so risks damaging the unpowered device (although the limited current provided by the pullup resistors should mitigate this).

If you want to have an unpowered device on the bus you **must** isolate it from the bus.  I use the PCA9306 as in [this answer](https://arduino.stackexchange.com/a/59882/4143), but other devices are available.

Did you kill the device by shorting it out? Possibly. It depends what you shorted to where. 3.3V directly onto the SDA or SCL pin while the device is unpowered may well have killed that pin.


body:
I'm new to Arduino and embedded, but understand that it is often better to use global instead of local variables (such as [here][1] or [here][2]).

I have this simple code (from [here][3]):

    //Libraries
    #include <DHT.h>;

    //Constants
    #define DHTPIN 2     // what pin we're connected to
    #define DHTTYPE DHT22   // DHT 22  (AM2302)
    DHT dht(DHTPIN, DHTTYPE); //// Initialize DHT sensor for normal 16mhz Arduino

    //Variables
    float hum;  //Stores humidity value
    float temp; //Stores temperature value

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

    }

    void loop()
    {
        //Read data and store it to variables hum and temp
        hum = dht.readHumidity();
        temp= dht.readTemperature();
        //Print temp and humidity values to serial monitor
        Serial.print("Humidity: ");
        Serial.print(hum);
        Serial.print(" %, Temp: ");
        Serial.print(temp);
        Serial.println(" Celsius");
        delay(2000); //Delay 2 sec.
    }

My ancient C programmer training (Unix servers) says I must move variables hum and temp to loop(), or is it better on Arduino to leave them as globals?

  [1]: https://arduino.stackexchange.com/questions/41493/are-global-variables-evil-in-arduino
  [2]: https://arduino.stackexchange.com/questions/29113/avoid-global-variables-with-classes
  [3]: https://www.instructables.com/id/How-to-use-DHT-22-sensor-Arduino-Tutorial/

title: Global or local

Answers: 3

body:
The general rule of good practice is to minimize the scope of a variable to necessary minimum. Write the code to be readable and maintainable, don't do [premature optimization][1].

The variables hum and temp should be defined only in loop(). The compiler can optimize it by putting them to global space or using MCU registers only, to avoid repeated creation on stack.

  [1]: http://wiki.c2.com/?PrematureOptimization

body:
No. If you have the choice, locals are usually better, because they
minimize the risk of name collision, and they help make the program
clearer by keeping the variable definition close to the place where it
is used. In your example, `hum` and `temp` should be locals, as there is
no good reason to make them globals.

However, sometimes you don't have the choice. If a variable is used in
both `setup()` and `loop()`, then it needs to be global. This is the
case of `dht` in your example.

Sometimes a variable is used in many functions. Even if you can make it
local, by passing it around through function parameters, doing so
doesn't make the program more readable. In that case you may also prefer
to keep it global.

Sometimes a variable that is used in only one function needs to be
statically allocated in order to preserve its value across calls to the
function. In this case the variable could be a `static` local. However,
since the `static` keyword is somewhat obscure for beginner programmers,
Arduino tutorials tend to use globals whenever static storage is needed.
You are not required to follow this practice, although you may want to
if you are writing for an audience of novices.

In any case, the take away of your first two links is _not_ that you
should prefer globals: it's that sometimes there is a good reason for
making a variable global, and _that's fine_.

body:
Not an answer, but I thought some of you may be interested in the C coding standards of *some* projects in the 1990s (based on the EDS standards, if I remember correctly).

A summary of the rules is:

 - No goto
 - No global variables
 - All functions (including main) to return an integer which is either SUCCESS or FAILURE
 - All variables declared at start of function
 - All variables declared on a separate line
 - No "in-line" initialising of variables
 - All variables initialised, usually to zero, including mallocs
 - No in-line if's
 - Probably more things that I can't remember

An example program:

    #include <stdio.h>
    #include <stdlib.h>

    #define SUCCESS 0
    #define FAILURE !SUCCESS

    int log_error(char *msg) {
      int rv;

      rv = SUCCESS;

      fprintf(stderr, "%s\n", msg);

      return(rv);
    }

    int function2(void) {
      int rv;

      rv = SUCCESS;

      return(rv);
    }

    int function1(void) {
      int rv;
      int i;
      char *mem;

      rv = FAILURE;
      i = 0;
      mem = 0;

      if(NULL == (mem = malloc(400))) {
        log_error("Malloc error");
      } else {
        for(i=0; i<400; i++) {
          mem[i] = 0;
        }
        if(SUCCESS != (rv = function2())) {
          log_error("function2");
        } else {
          rv = SUCCESS;
          free(mem);
        }
      }
      return(rv);
    }

    int main(int argc, char **argv) {
      int rv;

      rv = FAILURE;

      if(SUCCESS != (rv = function1())) {
        log_error("function1 error");
      }

      return(rv);
    }

Bit different to the way K&R wrote UNIX, and perhaps not too relevant to embedded? I'm not sure which I prefer, I guess both styles have their place depending on the makeup of a team :)


body: I am using fingerprint module r307 and LCD together. In that, I am using 2,3 digital pins of arduino for data transfer to the fingerprint.(I tried other pin configurations for this but it didn't work) But as I am connecting LCD, it also requires same 2,3 digital pins of arduino and it is not possible for me to use 2 and 3 pins of Arduino for both lcd and fingerprint sensor for data transfer. Can you please suggest an alternative to this. Can we use analog pins of arduino as digital ones and if so the how?? PLEASE HELP... Thank you!!

title: How can we use two devices at the same time with arduino?

Answers: 1

body:
> Can we use analog pins of arduino as digital ones and if so the how??

Yes. You just treat them the same as any other digital pin.  On an Arduino all pins are digital. It's just that some have *additional* functionality, like analog input, or PWM, or serial, or SPI, etc.


body: Why does the MPU6050 IMU sensor not require calibration? I've used other gyro sensors on RC helicopters that required calibration at boot. Also, how does it know what its neutral position is considering that I don't need to calibrate it?

title: MPU6050 Calibration

Answers: 1

body:
**It's not entirely true that it does not require any calibration at all.**

The MPU60X0 family's triple-axis MEMS gyroscope has certain features that **reduce** the need for calibration. These features are, as mentioned by Juraj, and on the datasheet:

 - Enhanced bias
 - Sensitivity temperature stability

This does not mean the sensor is 100% properly calibrated right out of the box, which means if you need it to be extremely accurate, you'd probably have to do some manual calibration on top of the built-in calibration features.

There is a discussion about this on this [Github issue][1]. I suggest reading up on that and you might be able to answer your own questions. They are also referring to [this datasheet][2] (Direct Download).

  [1]: https://github.com/universam1/iSpindel/issues/6
  [2]: https://github.com/universam1/iSpindel/files/634097/MPU-6000-Datasheet1.pdf


body:
 i am trying to make some kind of an amplifier. I got an amp board but want to read out the value from the potentiometer. The problem is that this pot is connected to the amp and has to be connected to the amps power Is there any way i can still read data (with an arduino) so that i can have a volume percentage on a lcd? Or is this imposible?

Amp 24v Potentiometer = 6pin. B50k

also what zould happen if i connect a 10k resistor instead of a 50k ressistor (audio potentiometer) what would the effect be?

title: Arduino potentiometer (external power) with amplifier

Answers: 2

body:
It's impossible. The pot is most probably acting as a passive variable attenuator. As such the top end will be the incoming audio signal, the lower end will be ground, and the wiper will be the attenuated incoming signal. There's not a lot you can do with that.

You would need to replace the pot with an equivalent triple pot (if such a thing exists) and have one third of it connected to the Arduino.  The pot you have at the moment is a dual pot, and a log taper at that.

Alternatively adding some kind of quadrature (motor) encoder to the shaft of the pot may be a possibility.

body:
A few options come to my mind:

 - I see you're using a double potentiometer, if you're using only one of it's outputs to control, you can use the other output to measure it's setting. (Or indeed use a "triple potentiometer" or added encoder as Majenko suggested.)
 - Use the Arduino as an intermediate (have the potentiometer as an input on the Arduino and control the output accordingly on the output of the Arduino).
 - Measure the output of the potentiometer. I'm not quite sure but the resistance over the potentiometer shouldn't be anything different depending on what is connected as well. Though you could also measure the output voltage on the potentiometer and from there deduce what it's value is (which may be difficult if it's an audio signal on this point in your system).


body:
I'm trying to cut my esp8266 range down to about a meter to save power.  I know that I can adjust output power but I don't know enough to understand what a given setting will actually yield.

I can set zero to kill it or 20.5 to set max range, but what setting is appropriate for a meter or so?  Is there a rule of thumb?

title: WiFi.setOutputPower();

Answers: 1

body:
The actual WiFi range is highly dependent on many more factors than just the TX power:

1. The antenna gain, directionality, and orientation of the receiver
2. The antenna gain, directionality, and orientation of the transmitter
3. The proximity of radio-reflective objects nearby (metal)
4. The proximity of radio absorbing objects nearby (humans)
5. RF Black Magic

In practice, test your situation by running a series of tests at lower and lower power settings until you get an unreliable connection, then bump it up a couple of notches from there.

Do not rely on transmitter power for security, however. You cannot stop someone from pointing a high-gain antenna at your device and communicating with it from a distance farther than 1 meter. TX power reduction should primarily be for energy conservation.


body:
I am now on a 3 Phase SPWM inverter project, and i got this code from this [article][1]. It works perfectly on simulation. But the problem is, i can't make the output frequency variable. I intend to vary the frequency at range 0 to 100 Hz and use it to control the speed of 3 phase induction motor. Could anyone help me, please? Any advice or maybe you got a code that works perfectly in controlling spwm inverter frequency. Here is the code of 3 phase spwm inverter. Oh, i am using Arduino Mega by the way.

                int i=0;
                int j=0;
                int k=0;
                int x=0;
                int y=0;
                int z=0;
                int OK=0;
                int OK1=0;
                int OK2=0
                int OK3=0;
                int OK4=0;
                int sinPWM[]={1,2,5,7,10,12,15,17,19,22,24,27,30,32,34,37,39,42,
                44,47,49,52,54,57,59,61,64,66,69,71,73,76,78,80,83,85,88,90,92,94,97,99,
                101,103,106,108,110,113,115,117,119,121,124,126,128,130,132,134,136,138,140,142,144,146,
                148,150,152,154,156,158,160,162,164,166,168,169,171,173,175,177,178,180,182,184,185,187,188,190,192,193,
                195,196,198,199,201,202,204,205,207,208,209,211,212,213,215,216,217,219,220,221,222,223,224,225,226,227,
                228,229,230,231,232,233,234,235,236,237,237,238,239,240,240,241,242,242,243,243,244,244,245,245,246,246,
                247,247,247,248,248,248,248,249,249,249,249,249,255,255,255,255,249,249,249,249,249,248,
                248,248,248,247,247,247,246,246,245,245,244,244,243,243,242,242,241,240,240,239,238,237,237,236,235,234,
                233,232,231,230,229,228,227,226,225,224,223,222,221,220,219,217,216,215,213,212,211,209,208,207,205,204,
                202,201,199,198,196,195,193,192,190,188,187,185,184,182,180,178,177,175,173,171,169,168,166,164,162,160,
                158,156,154,152,150,148,146,144,142,140,138,136,134,132,130,128,126,124,121,119,117,115,113,110,108,106,
                103,101,99,97,94,92,90,88,85,83,80,78,76,73,71,69,66,64,61,59,57,54,52,49,47,44,42,39,37,34,32,30,
                27,24,22,19,17,15,12,10,7,5,2,1};

                int potinput = A1;
                int potfreq = A2;
                float potinputval;
                float potfreqval;
                float A;
                float F;

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

                pinMode(4, OUTPUT);
                pinMode(13,OUTPUT);
                pinMode(9,OUTPUT);
                pinMode(10,OUTPUT);
                pinMode(2,OUTPUT);
                pinMode(5,OUTPUT);

                cli();// stop interrupts
                TCCR0A=0;//reset the value
                TCCR0B=0;//reset the value
                TCNT0=0;//reset the value
                //0b allow me to write bits in binary
                TCCR0A=0b10100001;//phase correct pwm mode
                TCCR0B=0b00000001; //no prescaler

                TCCR2A=0;//reset the value
                TCCR2B=0;//reset the value
                TCNT2=0;//reset the value
                //0b allow me to write bits in binary
                TCCR2A=0b10100001;//phase correct pwm mode
                TCCR2B=0b00000001; //no prescaler

                TCCR3A=0;//reset the value
                TCCR3B=0;//reset the value
                TCNT3=0;//reset the value
                //0b allow me to write bits in binary
                TCCR3A=0b10100001;//phase correct pwm mode
                TCCR3B=0b00000001; //no prescaler
                TCCR1A=0;//reset the value
                TCCR1B=0;//reset the value
                TCNT1=0;//reset the value
                OCR1A=509;// compare match value
                TCCR1B=0b00001001; //WGM12 bit is 1 for CTC mode and no prescaler

                TIMSK1 |=(1 << OCIE1A);// enable interrupts

                sei();//stop interrupts
                }
                ISR(TIMER1_COMPA_vect){// interrupt when timer 1 match with OCR1A value
                if(i>313 && OK==0){// final value from vector for pin 13
                i=0;// go to first value of vector
                OK=1;//enable pin 4
                }
                if(i>313 && OK==1){// final value from vector for pin 4
                i=0;//go to firs value of vector
                OK=0;//enable pin 13
                }
                x = round(A*sinPWM[i]); // x take the value from vector corresponding to position i(i is zero indexed)
                i=i+1;// go to the next position
                if(OK==0){
                OCR0B=0;//make pin 4 0
                OCR0A=x;//enable pin 13 to corresponding duty cycle
                }
                if(OK==1){
                OCR0A=0;//make pin 13 0
                OCR0B=x;//enable pin 4 to corresponding duty cycle
                }

                if ((i==209) || OK1==1){//if i equal with 209 enable second signal
                OK1=1;//mantain if function
                if(j>313 && OK2==0){// final value from vector for pin 10
                j=0;// go to first value of vector
                OK2=1;//enable pin 9
                }
                if(j>313 && OK2==1){// final value from vector for pin 9
                j=0;//go to firs value of vector
                OK2=0;//enable pin 10
                }
                y = round(A*sinPWM[j]);// y take the value from vector corresponding to position j(j is zero indexed)
                j=j+1;// go to the next position
                if(OK2==0){
                OCR2B=0;//make pin 9 0
                OCR2A=y;//enable pin 10 to corresponding duty cycle
                }
                if(OK2==1){
                OCR2A=0;//make pin 10 0
                OCR2B=y;//enable pin 9 to corresponding duty cycle
                }
                }
                if ((j==209) || OK3==1){//if j equal with 209 enable third signal
                OK3=1;//mantain if function
                if(k>313 && OK4==0){// final value from vector for pin 5
                k=0;// go to first value of vector
                OK4=1;//enable pin 2
                }
                if(k>313 && OK4==1){// final value from vector for pin 2
                k=0;//go to firs value of vector
                OK4=0;//enable pin 5
                }
                z=round(A*sinPWM[k]);// z take the value from vector corresponding to position k(k is zero indexed)
                k=k+1;// go to the next position
                if(OK4==0){
                OCR3B=0;//make pin 2 0
                OCR3A=z;//enable pin 5 to corresponding duty cycle
                }
                if(OK4==1){
                OCR3A=0;//make pin 5 0
                OCR3B=z;//enable pin 2 to corresponding duty cycle
            }
            }
            }
            void loop() {

              potinputval = analogRead(potinput);
              A = potinputval/1023;

              potfreqval = analogRead(potfreq);
              F = map(potfreqval,1023,0,0,50);}

  [1]: http://www.eprojectszone.com/how-to-generate-three-phase-spwm-signal-with-arduino/
  [2]: https://github.com/tardate/LittleArduinoProjects/blob/master/Electronics101/SwitchModePowerSupplies/BasicInvertingBuckBoostAvrControl/BasicInvertingBuckBoostAvrControl.ino
  [3]: https://pastebin.com/G7N6tFbM

title: Controlling output frequency of 3 Phase SPWM Inverter

Answers: 1

body:
In this sketch the PWM values, matching a sampled sine curve, are stored in integer array sinPWM[]. The values from sinPWM (1 - 255) are used unmodified (via intermediate variables x, y and z) to set the various timing registers (OCR0A/B, OCR2A/B and OCR3A/B) which control the pulse width modulation. In this way the amplitude(s) of the generated sine wave(s) will be constant.

If you want to control the speed of the motor you have to multiply the values from sinPWM with a factor between 0 and 1. The most logical place is to do that when the values from sinPWM are transferred to the intermediate variables x, y and z. Example: x=round(0.8 * sinPWM[i]). The factor, 0.8 in this example, you can of course replace by a variable which value is derived from an analogRead() of a pin connected to a potmeter or some sensor. But make sure to convert it to a value in the range 0-1 before you use it in the calculation.


body:
I am trying to use Arduino as Modbus- RTU slave and Raspberry Pi as a Modbus master I have interfaced Max485 (RS485 to TTL converter) with Arduino and Rs485 to USB converter in Raspberry Pi, Initially, I was able to send data from Arduino to Raspberry Pi, but the data seems to inconsistent and fails to read most times

I am using https://github.com/smarmengol/Modbus-Master-Slave-for-Arduino for Arduino Minimal Modbus for raspberry pi

Connections:

* DI(max485)- TX ( Arduino),
* DE(max485) -D2 ( Arduino),
* RE(max485) - D2( Arduino),
* Ro(max485) - RX( Arduino),
* Vcc(max485) -5v( Arduino),
* Gnd (max485)- GND( Arduino)

code for Arduino

    #include <ModbusRtu.h>
    uint16_t au16data[6] = {};
    Modbus slave(5,0,2);
    void setup() {
      slave.begin(19200,SERIAL_8N2 );
     }
    void loop() {
      au16data[0]=100;
      au16data[1]=200;
      au16data[2]=300;
      au16data[3]=400;
      au16data[4]=500;
      au16data[5]=600;
      slave.poll( au16data, 6 );
      delay(3000);
    }
python code

    import minimalmodbus
    from datetime import datetime
    import time

    instrument = minimalmodbus.Instrument('/dev/ttyUSB0', 5)
    instrument.serial.baudrate = 19200
    instrument.serial.bytesize = 8
    instrument.serial.parity = minimalmodbus.serial.PARITY_NONE
    instrument.serial.stopbits = 2
    instrument.serial.timeout =6
    instrument.mode = minimalmodbus.MODE_RTU

    while(1):
        try:
            val = instrument.read_registers(0,6)
            # Registernumber, number of decimals
            print val
        except IOError:
            error_msg = "Failed to read from device"
            error_time = datetime.now()
            print "IO Error Time",error_time.isoformat(),error_msg

        except ValueError:
            error_msg = "Failed to read CRC"
            error_time = datetime.now()
            print "Value Error Time",error_time.isoformat(),error_msg
        time.sleep(2)
[![connection][1]][1]

but now I am getting The exception of failed to read

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

title: Arduino Modbus slave error

Answers: 0


body:
I am trying to make a circuit using [Nodemcu ESP8266][1] to control the speed and direction of 3 DC servo motors, however I am short of analog pins.
So are there any ways to increase the number of analog pins?
Or are there other WiFi modules like the ESP8266, but with more number of analog pins?

  [1]: http://www.nodemcu.com/index_en.html

title: ESP8266 like WiFi modules

Answers: 1

body:
How many PWMs do you need?

[Here][1] you can find a useful description about PWMs on ESP8266 NodeMCU.

According to image, ESP8266 NodeMcu has 9 PWMs pin.

[![ESP8266 PWM Pinout][2]][2]

  [1]: https://www.electronicwings.com/nodemcu/nodemcu-pwm-with-arduino-ide
  [2]: https://i.stack.imgur.com/hdiUX.png


body:
This sketch runs well with SoftwareSerial define and the monitor displays device modbus values. But now, i want to replace SoftwareSerial by Serial1
and i have no data.

This is the sketch with SoftwareSerial:

    #include <SoftwareSerial.h>
    #define SSerialRX        10  //Serial Receive pin
    #define SSerialTX        11  //Serial Transmit pin
    #define SSerialTxControl 40   //RS485 Direction control
    #define RS485Transmit    HIGH
    #define RS485Receive     LOW

    SoftwareSerial RS485Serial(SSerialRX, SSerialTX); // RX, TX
    byte byteSend;

    void setup()
    {
      Serial.begin(9600);
      pinMode(SSerialTxControl, OUTPUT);
      digitalWrite(SSerialTxControl, RS485Transmit);  // Init Transceiver
      RS485Serial.begin(9600);
    }
    void loop()
    {
      delay(500);
      if (RS485Serial.available())
      { for(int i=0; i<7; i++)
        {
        byteSend = RS485Serial.read();   // Read the byte

        Serial.print(byteSend, HEX);
        Serial.print(" ");
        }
      }
      digitalWrite(SSerialTxControl, RS485Transmit);  // Init Transceiver
      byte request[] = {0x01, 0x03, 0x00, 0x00, 0x00, 0x01, 0x84, 0x0A};
      RS485Serial.write(request, sizeof(request));

      digitalWrite(SSerialTxControl, RS485Receive);
      Serial.println(" ");
    }

And the sketch i tried with Serial1 (pin 19(Rx) and 18(Tx)):

    #define SSerialTxControl 40   //RS485 Direction control
    #define RS485Transmit    HIGH
    #define RS485Receive     LOW

    byte byteSend;

    void setup()
    {
      Serial.begin(9600);
      pinMode(SSerialTxControl, OUTPUT);
      digitalWrite(SSerialTxControl, RS485Transmit);  // Init Transceiver
      Serial1.begin(9600);
    }
    void loop()
    {
      delay(500);
      if (Serial1.available())
      { for(int i=0; i<7; i++)
        {
        byteSend = Serial1.read();   // Read the byte

        Serial.print(byteSend, HEX);
        Serial.print(" ");
        }
      }
      digitalWrite(SSerialTxControl, RS485Transmit);  // Init Transceiver
      byte request[] = {0x01, 0x03, 0x00, 0x00, 0x00, 0x01, 0x84, 0x0A};
      Serial1.write(request, sizeof(request));

      digitalWrite(SSerialTxControl, RS485Receive);
      Serial.println(" ");
    }

Can you help me to find my mistake ?

title: Can't replace SoftwareSerial by Serial1 on Mega board

Answers: 1

body:
>  what is the best way to solve it, using Serial1?

With either serial device, you need to collect characters until you have an entire message. If every message will be a fixed number of bytes, you can wait until the return value of the Serial::available() call indicates it has that many characters, then collect them into a buffer and process them. But this assumes you'll never get a badly-formed message. If you do, the incoming bytes will get out of sync with your program.
A better way is to collect bytes into your buffer (but do nothing with them) until you have a complete message (by byte-count, newline character, or however you need to recognize that it is complete) or your buffer is about to overflow, and then either process them, or if your buffer filled and the contents doesn't look like a valid message, discard it and try to re-synchronize with the source. That may mean reading and ignoring bytes until you get a newline, and dealing with the fact you got a garbled message, or telling your source to restart or reset. The exact method (or whether you even want to bother detecting bad messages) depends on the particular situation. Will someone die if you fail? Will something catch fire, burn parts, lose weeks worth of good data, ... ? Or is this an experiment whose consequence of failure are zero or at least not worth any effort to detect it?


body:
Ok so as some readers might have seen, my current project involves using MPU's. The idea is sending data via CAN bus to a controlling MCU to then send to a raspberry pi to perform the calculations required for my MATLAB/ Simulink model.

After a lot of searching i found this great post/ blog on how to set I2C registers.

[Setting I2C Registers][1]

 With this, i was able to avoid using a library from Github. I do NOT think i am better than the people writing the libraries, just it's difficult to truly understand code/ a project with a downloaded library and it just stuffed at the top of a piece of butchered example code.

Using the above blog, i learnt how to control an MPU6050 myself in a very basic sense. I am now trying to use an MPU9250 for the sake of extra speed over SPI. However i am trying to understand how to set registers using the SPI interface. For example below for I2C you could write;

      Wire.begin();
      Wire.beginTransmission(MPU_addr);
      Wire.write(0x6B);  // PWR_MGMT_1 register
      Wire.write(0);     // set to zero (wakes up the MPU-6050)
      Wire.endTransmission(true);

 and then access the registers like below;

    Wire.beginTransmission(MPU_addr);
      Wire.write(0x3B);  // starting with register 0x3B (ACCEL_XOUT_H)
      Wire.endTransmission(false);
      Wire.requestFrom(MPU_addr,14,true);  // request a total of 14 registers
      AcX=Wire.read()<<8|Wire.read();  // 0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L)
      AcY=Wire.read()<<8|Wire.read();  // 0x3D (ACCEL_YOUT_H) & 0x3E (ACCEL_YOUT_L)
      AcZ=Wire.read()<<8|Wire.read();  // 0x3F (ACCEL_ZOUT_H) & 0x40 (ACCEL_ZOUT_L)
      Tmp=Wire.read()<<8|Wire.read();  // 0x41 (TEMP_OUT_H) & 0x42 (TEMP_OUT_L)
      GyX=Wire.read()<<8|Wire.read();  // 0x43 (GYRO_XOUT_H) & 0x44 (GYRO_XOUT_L)
      GyY=Wire.read()<<8|Wire.read();  // 0x45 (GYRO_YOUT_H) & 0x46 (GYRO_YOUT_L)

my question, is how do you read and write to registers in a similar way via SPI. I've found lots of info on using SPI, but not configuring sensors etc with it in a nice, "SPI configuration for Dummies" type of thing. Is my googling just terrible?

EDIT - My goal is learn the theory behind making a basic library for a sensor, not to make my own SPI library. For example, make a library that can be used to control an MPU9250 using SPI commands to change registers. The last part is what i am struggling with. Interfacing with a sensor to change register values or read registers with SPI.

The link above is almost a crash course in how to use the wire library to interface with a sensor. How do you use the SPI library to change/ read register values.

EDIT2 - Is this the usual format for communicating with registers using SPI on arduino? Thanks

    digitalWrite(SS, LOW);
    SPI.transfer(0xF1);  // Read, Sensor 1...
    SPI.transfer(0x02);  // ... RESA register
    highByteA = SPI.transfer(0x00);  // Read High Byte of RESA
    lowByteA = SPI.transfer(0x00);  // Read Low Byte of RESA
    highByteB = SPI.transfer(0x00);  // Read High Byte of RESB
    lowByteB = SPI.transfer(0x00);  // Read Low Byte of RESB
    .
    .
    .
    digitalWrite(SS, HIGH);

thanks

[1]: https://thecavepearlproject.org/2017/11/03/configuring-i2c-sensors-with-arduino/

title: How to use SPI to set/ read registers for a sensor (Avoiding need for Github Lib)

Answers: 0


body:
I recently started working on an security camera system, with an arduino uno and an OV7670 camera without FIFO memory, and an ESP-8266 to transfer the images to a webserver. Everything is working, except this:

The problem: My camera takes the images (QVGA resolution) twice every time, and collapse them into one image.

My images looks like this:

[![https://i.imgur.com/JgARUbX.png][1]][1]

One (240*320) QVGA image is built by two (120*320) half image.
My camera takes the two images AFTER each other, not just duplicates the first part.

(After I got one line of the image ready I send it with SoftwareSerial to ESP8266, and that send it forward...)

I'm trying to changeing the scaling registers with different combinations, without success.

I followed this tutorial at the beginning, and modified its code.
https://hkalasua.wordpress.com/2017/09/11/ov7670-arduino-sd/

Arduino code:

    #include <Wire.h>
    #include <SoftwareSerial.h>

    SoftwareSerial ESPserial(10, 11); // RX | TX

    void Init_YUV422(){
      WriteOV7670(0x12, 0x00);//COM7
      WriteOV7670(0x8C, 0x00);//RGB444
      WriteOV7670(0x04, 0x00);//COM1
      WriteOV7670(0x40, 0xC0);//COM15
      WriteOV7670(0x14, 0x6A);//COM9
      WriteOV7670(0x3D, 0x40);//COM13
      }

    void Init_QVGA(){
      WriteOV7670(0x0C, 0x04);//COM3 - Enable Scaling
      WriteOV7670(0x3E, 0x19);//COM14
      WriteOV7670(0x72, 0x11);//
      WriteOV7670(0x73, 0xF1);//
      WriteOV7670(0x17, 0x16);//HSTART
      WriteOV7670(0x18, 0x04);//HSTOP
      WriteOV7670(0x32, 0xA4);//HREF
      WriteOV7670(0x19, 0x02);//VSTART
      WriteOV7670(0x1A, 0x7A);//VSTOP
      WriteOV7670(0x03, 0x0A);//VREF
      WriteOV7670(0x70, 0x00);//SCALING_YSC

      }

    void Init_OV7670() {
      //Reset All Register Values
      WriteOV7670(0x12, 0x80);
      delay(100);

      WriteOV7670(0x3A, 0x04); //TSLB

      WriteOV7670(0x13, 0xC0); //COM8
      WriteOV7670(0x00, 0x00); //GAIN
      WriteOV7670(0x10, 0x00); //AECH
      WriteOV7670(0x0D, 0x40); //COM4
      WriteOV7670(0x14, 0x18); //COM9
      WriteOV7670(0x24, 0x95); //AEW
      WriteOV7670(0x25, 0x33); //AEB
      WriteOV7670(0x13, 0xC5); //COM8
      WriteOV7670(0x6A, 0x40); //GGAIN
      WriteOV7670(0x01, 0x40); //BLUE
      WriteOV7670(0x02, 0x60); //RED
      WriteOV7670(0x13, 0xC7); //COM8
      WriteOV7670(0x41, 0x08); //COM16
      WriteOV7670(0x15, 0x20); //COM10 - PCLK does not toggle on HBLANK
    }

    void WriteOV7670(byte regID, byte regVal) {
      // Slave 7-bit address is 0x21.
      // R/W bit set automatically by Wire functions
      // dont write 0x42 or 0x43 for slave address
      Wire.beginTransmission(0x21);
      // Reset all register values
      Wire.write(regID);
      Wire.write(regVal);
      Wire.endTransmission();
      delay(1);

    }

    void ReadOV7670(byte regID) {
      // Reading from a register is done in two steps
      // Step 1: Write register address to the slave
      // from which data is to be read.
      Wire.beginTransmission(0x21); // 7-bit Slave address
      Wire.write(regID);  // reading from register 0x11
      Wire.endTransmission();

      // Step 2: Read 1 byte from Slave
      Wire.requestFrom(0x21, 1);
      Serial.print("Read request Status:");
      Serial.println(Wire.available());
      Serial.print(regID, HEX);
      Serial.print(":");
      Serial.println(Wire.read(), HEX);
    }

    void XCLK_SETUP(void) {
      pinMode(9, OUTPUT); //Set pin 9 to output

      //Initialize timer 1

      //WGM13, WGM12, WGM11 & WGM10 bits SET- Fast PWM mode
      //COM1A0 SET- Toggle OC1A on compare match
      TCCR1A = (1 << COM1A0) | (1 << WGM11) | (1 << WGM10);
      //SET CS10 bit for clock select with no prescaling
      TCCR1B = (1 << WGM13) | (1 << WGM12) | (1 << CS10);
      //Output Compare Register 1A(OCR1A) = 0
      //This will lead to a match on every clock cycle
      //Toggle OC1A output pin on every match instance
      //Therefore, the generated waveform will have half
      //the frequency of the driving clock i.e. 8Mhz
      //OC1A pin- PB1 (alternate functn) pin i.e. Arduino pin 9
      OCR1A = 0;

    }

    // Two Wire Interface Setup
    // Sets the frequency of the SCL line
    // Default is 100KHz so we won't use this function
    void TWI_SETUP(void) {
      //Set prescaler bits in TWI Status Register (TWSR) to 0
      TWSR &= ~3;
      //Set SCL frequency to 100KHz
      //SCLfreq = CPUfreq/(16 + 2(TWBR) - 4^(TWPS))
      //TWBR = 72, TWPS(prescaler) = 0
      TWBR = 72;

    }

    void OV7670_PINS(void) {
      //Setup Data input pins and Interrupt pins
      //DDRC bits 3:0 = 0 =>  bits configured as Data Inputs
      //DDRC 3:0 - A3,A2,A1,A0
      DDRC &= ~15;//low d0-d3 camera

      //~(0b11111100) = 0b00000011
      //make DDRD 7:2 = 0 => Inputs
      //d7-d4 as data inputs, d3-INT1 is VSYNC and d2-INT0 is PCLK
      DDRD &= ~252;
    }

    void QVGA_Image() {
      int h, w;

      while (!(PIND & 8));//wait for high
      while ((PIND & 8));//wait for low

      byte dataBuffer[320];

      h = 240;
      while (h--) {
        w = 320 ;

        while (w--) {
          while ((PIND & 4));   //wait for low
          dataBuffer[319 - w] = (PINC & 15) | (PIND & 240);
          while (!(PIND & 4));  //wait for high
          while ((PIND & 4));   //wait for low
          while (!(PIND & 4));  //wait for high
        }

        //sendig the line to ESP
        ESPserial.write(dataBuffer, 320);
      }

      delay(100);
    }

    void setup() {
      Serial.begin(115200);
      ESPserial.begin(115200);
       noInterrupts(); //Disable all interrupts
      XCLK_SETUP();   //Setup 8MHz clock at pin 11
      OV7670_PINS();  // Setup Data-in and interrupt pins from camera
      delay(1000);
      TWI_SETUP();    // Setup SCL for 100KHz
      interrupts();
      Wire.begin();

      Init_OV7670();
      Init_QVGA();
      Init_YUV422();
      WriteOV7670(0x11, 0x1F); //Range 00-1F
      // noInterrupts();

     QVGA_Image();

    }

    void loop() {
     /* ..Not relevant for this problem.. */
    }

I'd be very greatful, if you can help!..
...this is a really annoying problem..

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

title: Ov7670 (without FIFO) captures the images twice at the same time

Answers: 0


body:
I'm trying to control a relay both via Bluetooth and using a switch. The problem is that, when the LED is off, I can turn it on with the switch but then if I turn off the switch the relay will stay on. Is there something wrong with my code? Thanks in advance. The switch is installed as follows:
[![Switch][1]][1]

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

Here is my code: Switch is connected to pin 3 and the relay is connected to pin 2.
<!-- language-all: lang-cpp -->

    //bluetooth hc-06
    int ledPin = 2; // usamos un pin de salida al LED
    int state = 0; // Variable lectrura serial
    int interruptor=3;

    void setup() {
        pinMode(ledPin, OUTPUT);   //Declara pin de Salida
        pinMode(interruptor, INPUT);
        digitalWrite(ledPin, LOW); //Normalmente Apagado
        Serial1.begin(9600);
        }

    void loop() {
      int valor=digitalRead(interruptor);

      if(Serial1.available() > 0){
           state = Serial1.read();
      } // esta parte del código es para solo 1 Carácter o Unidad.

     if (state == '0'&& valor== LOW) {
        digitalWrite(ledPin, LOW);
        Serial1.println("LED: off");
     }

     else
     if (state == '1' || valor== HIGH) {
         digitalWrite(ledPin, HIGH);
         Serial1.println("LED: on");
     }

    }

New code:

    //bluetooth hc-06
    int ledPin = 2; // usamos un pin de salida al LED
    int state = 1; // Variable lectrura serial
    int interruptor=3;

    void setup() {
        pinMode(ledPin, OUTPUT);   //Declara pin de Salida
        pinMode(interruptor, INPUT);
        digitalWrite(ledPin, LOW); //Normalmente Apagado
        Serial1.begin(9600);
        }

    void loop() {
      int valor=digitalRead(interruptor);
     //si el modulo ha mandado dato, guardarlo en estado.

      if(Serial1.available() > 0){
           state = Serial1.read();
      } // esta parte del código es para solo 1 Carácter o Unidad.

     // si el estado es 0 ese sería Apagado “OFF”
     if (valor== LOW) {
        digitalWrite(ledPin, LOW);
        Serial1.println("LED: off");
     }

     // de lo contrario si el estado es 1 ese sería Encendido “ON”
     else
     if (valor== HIGH) {
         if (state== 1){
         digitalWrite(ledPin, HIGH);
         Serial1.println("LED: on");
         }
         else if (state== 0){
         digitalWrite(ledPin, LOW);
         Serial1.println("LED: off");

         }
     }

    }

title: Digital Input using a button doesn't work properly when using it to control a relay

Answers: 2

body:
You have to invalidate the `state` variable when `Serial` is not available, otherwise you will produce strange behaviours.

```cpp
if (Serial1.available() > 0) {
    state = Serial1.read();
} else {
    state = -1; // not valid
}
```

Also, serial values will be characters, not integers, so compare with character values, e.g.,

```cpp
if (state == '1')
```

body:
Well, there are a couple of problems.

In the original SW, you are checking for `state = '0'` and `state = '1'`, but the initial value of state is `0` (not `'0'`). For this reason both tests always return false.

In addition, avoid setting conditions when not necessary. `else` already mean "all the other options", so if you have one variable that can be only A or B, don't write `if A ... else if B ...`; the second condition is necessary (and meaningful) only if the condition is actually something you care of (so you want to exclude condition C).

I started modifying your sketch from the new version, and here are the things I modified:

 - Variables were set to type `uint8_t`; `int` is not efficient on 8-bit platforms, so use 8-bit variables whenever you can
 - Instead of using multiple triggers, I used a single variable (`ledState`) to calculate the state in each loop. This way it is much easier to track the modifications
 - simplified the input management: now it turns on the led when the input is high, and does nothing (leaves it off) when it is low
 - simplified the bluetooth management. With a `'1'` it turns on the led, and all the other chars set it off; if you need only a '0' to turn it off you can easily modify the parentheses to ignore other chars

This is the code I wrote. NOTE: I did not test it, so there may be residual bugs. Let me know if it works as you expect or want some additional clarifications:

    uint8_t ledPin = 2;
    uint8_t interruptor = 3;
    uint8_t bluetoothState = '0';

    void setup() {
        pinMode(ledPin, OUTPUT);
        pinMode(interruptor, INPUT);
        digitalWrite(ledPin, LOW);
        Serial1.begin(9600);
    }

    void loop() {
     uint8_t ledState = LOW;

     if (digitalRead(interruptor)) {
      ledState = HIGH;
      Serial1.println("LED: on (switch)");
     }

     if(Serial1.available() > 0){
      bluetoothState = Serial1.read();
     }

     if (bluetoothState == '1') {
      ledState = HIGH;
      Serial1.println("LED: on (BT)");
     }

     digitalWrite(ledPin, ledState);
     if (ledState == LOW) {
      Serial1.println("LED: off");
     }
    }

Things still to do (IMHO):
 - make a robust button handler (for instance using the debounce library)
 - get rid of the serial debug outputs
 - make a better serial protocol


body:
I have a motorized curtain and I'm trying to understand its rf control signal in order to control it from my arduino.

I got the times, and checked the code is not static. I believe it has some kind of "sequencial counter" but I could not decode and understand the logic. In resume, I'm trying the get the operations the manufacturer do in order to obfuscate the payload.

The timings I got for the same key, pressed in sequence, are:

    396,400,396,804,396,408,800,800,396,408,396,408,396,408,396,408,800,400,400,796,404,400,804,800,804,396,400,800,804,800,400,400,404,404,400,404,400,400,404,400,804,396,404,796,24508,408,368,404,368,404,368,404,368,400,376,400,372,400,372,400,372,400,372,400,372,400,372,400,372,400,376,396,372,400,372,404,372,392,380,396,376,396,376,400,376,392,376,396,376,400,3872,396,384,392,384,420,384,420,384,420,384,416,792,408,388,812,388,416,388,416,388,416,388,416,388,412,796,408,392,400,392,408,392,808,388,412,392,412,392,412,796,404,396,804,796,404,392,404,392,404,396,804,796,404,396,400,396,804,800,400,396,400,396,400,396,804,396,408,800,804,392,408,396,408,396,408,396,408,800,400,400,800,396,408,804,796,804,396,400,800,804,800,400,404,400,404,400,400,404,404,400,400,808,392,404,796,24516,404,368,404,368,404,368,404,368,400,372,404,368,404,372,400,372,400,372,400,372,400,372,400,372,396,376,400,376,396,376,396,376,400,372,400,372,396,376,396,376,400,376,396,372,404,3868,400,380,392,384,420,384,416,388,420,384,420,788,408,388,812,388,416,388,416,388,416,384,416,392,412,796,404,392,404,392,404,392,804,396,416,388,408,396,412,796,404,392,808,796,404,392,404,392,404,392,808,796,400,396,400,400,800,804,400,392,404,396,400,396,800,400,404,804,800,396,408,396,408,400,400,400,404,804,396,404,796,400,404,804,800,804,396,400,800,804,796,400,404,400,404,400,404,400,400,404,404,804,392,404,796,24512,412,364,404,368,408,364,404,368,404,368,404,368,404,372,404,368,404,368,404,368,400,372,404,368,400,372,400,376,396,376,396,376,400,372,396,376,396,376,400,372,400,376,396,376,400,3868,400,380,392,384,420,384,416,388,416,388,420,788,412,384,816,384,416,388,416,388,416,388,416,388,416,792,408,388,404,392,408,388,812,388,416,388,412,392,412,796,400,396,808,796,404,392,404,396,400,396,804,800,400,396,400,396,804,800,400,396,400,396,400,396,804,396,408,800,804,396,404,400,408,396,404,400,404,804,396,400,800,396,408,804,796,808,396,400,796,808,796,400,404,400,404,400,404,400,404,400,400,808,392,404,796

    392,412,796,400,396,404,396,800,396,408,396,408,396,408,396,408,396,404,400,408,396,404,804,396,400,396,400,396,400,800,804,800,804,396,400,800,400,404,804,796,404,400,400,404,404,400,804,396,404,392,404,392,404,380,24124,404,368,408,368,404,372,400,368,404,368,400,372,404,368,404,368,404,372,400,372,400,372,400,372,400,372,400,372,400,376,396,372,400,376,396,376,396,376,396,376,396,376,396,376,400,3872,396,384,392,384,420,384,420,384,420,788,408,392,404,388,412,388,808,388,416,388,412,392,416,792,404,396,404,388,808,800,808,388,412,392,412,796,404,392,400,400,400,396,400,396,400,396,404,392,400,396,404,396,400,396,400,396,804,396,408,796,404,396,400,396,800,396,412,392,408,396,408,396,408,396,408,396,408,396,408,800,396,400,400,400,396,400,800,804,800,800,400,400,800,396,404,808,796,400,404,400,404,400,404,804,396,400,396,400,396,404,380,24124,408,368,404,368,404,368,404,368,404,368,404,368,400,372,400,372,404,368,404,372,400,372,400,372,400,372,396,376,400,372,400,372,396,380,392,376,400,376,396,376,396,376,396,376,400,3868,400,380,392,384,420,388,416,388,412,796,408,388,408,388,408,388,812,388,416,388,412,392,412,796,408,388,408,388,812,792,808,392,408,396,408,800,400,396,404,392,404,392,404,392,404,392,404,396,396,400,400,396,400,396,404,392,804,396,408,800,400,396,400,400,800,396,408,396,408,396,404,400,408,396,408,396,404,400,404,804,396,400,400,396,396,400,800,804,800,804,396,400,800,400,404,804,800,400,404,400,400,404,400,808,392,404,392,404,396,400,380,24124,404,368,412,364,404,368,404,368,404,368,404,368,404,368,404,372,400,368,404,372,400,372,400,372,400,372,400,372,400,372,400,372,400,376,396,376,396,376,400,372,396,376,400,372,400,3872,396,384,392,384,420,384,424,380,416,792,408,388,408,388,412,384,816,384,416,388,416,392,416,788,408,392,404,392,808,796,808,388,416,388,416,792,404,396,404,388,408,392,404,392,404,392,404,392,404,396,400,396,400,396,404,392,804,396,408,800,400,396,400,396,804,396,408,396,408,396,408,396,404,400,404,396,408,396,408,800,400,396,400

[This site helps visualize the timings][1]  (just copy and paste)

I believe it uses modulation ASK and Manchester Encoding (not sure about that), and the binary data I got is (the timings for third key press I did not save):

    1010101010100101101010101010010101011010101001011001010101100101011001010101101001101010101001011010011001011001101010101010010110

    1010101010010101011010101001010110011010100101010101010101010101101001010110101010101010100101010110011001011010011010101001010101

    1010101010011010101010101001101001011010100110101001010101011010011001010110010101101010100110101010011001011010101010101001101010

[This link][2] explain what I'm trying to do, but using a control from another manufacturer. The result, is better explained [here][3].

If is useful, I press the same key 2 times in other identical control and the timings I got are (I believe it changes the address and the 'counter'):

    408,400,408,400,412,396,408,396,416,400,816,388,412,792,820,796,816,792,416,396,820,384,412,796,416,388,416,396,412,396,416,392,412,396,820,384,420,788,24636,404,376,400,376,396,384,396,376,400,380,396,384,396,380,396,380,396,380,396,384,392,384,396,380,392,388,392,384,388,388,392,388,392,384,392,384,392,384,392,388,388,388,384,392,392,3900,392,392,384,396,412,396,408,404,412,392,412,804,404,400,804,400,408,404,408,396,408,400,412,396,408,808,400,404,400,400,400,404,800,404,408,400,404,408,400,812,392,408,804,400,408,400,404,408,400,408,400,816,800,404,400,408,400,816,800,408,400,408,400,404,404,816,388,412,796,408,400,408,400,408,396,412,400,412,396,820,388,412,792,820,792,816,796,416,392,820,388,412,796,412,396,412,392,416,392,416,396,416,388,824,384,416,792,24636,400,380,400,372,400,380,396,380,396,380,396,384,396,380,400,376,396,384,396,380,396,380,396,380,396,384,392,384,392,384,392,388,392,384,388,388,392,384,392,388,392,388,388,384,396,3896,392,392,388,396,408,400,412,392,416,396,412,800,404,400,808,396,412,400,408,396,412,400,408,400,408,804,400,404,400,400,396,404,808,400,408,400,408,404,404,808,396,404,804,404,400,408,400,408,404,404,404,812,800,404,404,404,404,816,796,408,400,408,400,408,400,816,388,412,792,412,400,412,396,412,396,412,396,412,396,820,388,412,792,820,796,816,796,412,392,820,392,412,792,416,392,412,396,416,392,412,396,416,392,824,384,420,788,24632,404,376,400,376,400,376,400,380,400,376,400,380,396,380,392,384,396,380,396,384,392,384,396,380,396,380,392,388,392,384,392,388,388,388,388,388,392,384,392,384,392,384,392,388,392,3896,392,396,384,392,416,396,408,400,412,396,412,804,400,400,808,400,408,400,408,400,408,400,408,400,408,808,396,404,396,408,396,400,804,404,408,400,408,400,404,812,396,404,804,408,400,404,400,408,400,408,400,816,800,408,400,408,400,812,800,408,400,408,400,408,400,816,388,412,800,408,396,412,396,412,396,412,396,412,396,820,388,412,796,816,796,816,792,416,392,820,388,420,788,412,396,416,388,420,392,416,392,412,396,820,384,420,788

    808,400,400,396,408,396,404,804,404,404,404,400,408,404,404,404,404,404,404,404,812,392,408,796,412,400,408,400,816,392,408,392,408,388,412,800,412,392,412,400,408,400,816,388,412,388,412,392,412,388,412,796,816,796,412,396,820,792,820,796,408,396,412,392,416,396,820,388,412,384,420,384,416,372,24248,404,376,396,380,400,376,400,376,400,380,396,380,396,380,396,380,400,380,392,388,392,380,396,384,392,384,392,384,396,380,392,384,392,388,392,384,392,388,388,388,388,388,388,388,396,3896,392,392,388,396,408,400,412,396,412,800,404,400,404,396,400,404,804,400,408,400,408,400,408,808,400,404,396,404,800,812,804,400,408,400,404,812,400,404,396,404,396,404,804,400,408,404,404,404,400,412,400,404,404,408,400,816,388,412,792,412,400,408,400,816,388,412,392,412,388,412,796,412,396,412,396,408,400,816,392,412,388,412,388,412,388,416,792,820,792,412,396,820,792,820,792,416,392,416,392,416,392,820,388,416,384,420,384,416,368,24248,404,376,400,380,396,380,400,376,400,376,400,380,392,384,396,380,400,380,392,384,396,384,392,380,392,384,396,384,392,384,392,388,388,388,388,388,392,388,388,384,392,388,388,388,396,3896,392,392,384,396,416,396,412,396,412,800,404,400,404,396,400,404,808,396,408,400,408,400,408,804,404,400,400,400,808,808,800,404,408,404,400,816,392,408,396,404,396,404,804,404,400,408,404,404,404,404,404,408,396,408,404,812,396,404,800,408,400,408,400,816,388,412,392,412,388,412,796,408,400,408,400,408,400,816,392,412,388,412,388,412,388,416,792,820,792,412,396,820,792,820,792,416,392,416,392,416,392,820,388,416,384,416,384,416,372,24248,404,376,404,372,404,376,400,376,396,380,400,376,400,380,396,380,396,380,396,380,396,384,396,380,396,384,388,388,392,384,392,384,392,384,392,388,388,384,392,392,388,388,384,388,392,3900,392,396,384,396,412,396,412,396,412,804,404,396,404,396,404,400,804,400,408,400,408,404,408,808,396,400,400,404,804,812,800,404,404,404,404,808,400,404,396,404,396,404,804,404,404,404,404,400,404,408,404,404,404,408,396,816,392,404,804,408,400,408,400,820,384,412,388

  [1]: http://test.sui.li/oszi/
  [2]: https://pushstack.wordpress.com/2014/04/14/reversing-somfy-rts/
  [3]: https://pushstack.wordpress.com/somfy-rts-protocol/

title: Decoding RF Signal

Answers: 0


body:
So I have this ESP 8266 v3 board that has a program. Running on it currently, it’s the example scan Network Program. No matter what program I send to it now I get a error complaining for board NodeMCU 1.0 (ESP-12E).
I have checked to assure that the com port is correct and is showing upload 11500 , cpu 80 MHz, flash size 4M, debug disabled. Debug level - none, iwip v2 low memory
Viable”flash”, exception enable, erase flash only sketch
Port 6 .
   Arduino 1.8.8 Windows 10
In error box print in red

    Board nodemcuv2. (platform, esp8266, package edp8266 is Unknown.
    Error compiling for board NodeMCU 1.0 (ESP-12E Module)

Used this board a few times without an issue, now no matter what I try it maintains the current scan program and I am unanticipated compile or upload to the board. Is it stuck in some sort of loop or what? Any help would be appreciated, thanks

title: Esp8266 -12E v3

Answers: 0


body:
In the [Adafruit_MotorShieldV2Library>Accel_MultiStepper](https://github.com/adafruit/Adafruit_Motor_Shield_V2_Library/blob/master/examples/Accel_MultiStepper/Accel_MultiStepper.ino) example, [AccelSteppers](https://www.airspayce.com/mikem/arduino/AccelStepper/classAccelStepper.html#afa3061ce813303a8f2fa206ee8d012bd) are initialized using the following *static* forwardstep1 and backwardstep1:

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

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

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

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

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

I intend to then use these AccelSteppers as members in a [MultiStepper](http://www.airspayce.com/mikem/arduino/AccelStepper/MultiStepper_8pde-example.html), which I'm skipping here because it shouldn't be relevant.

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

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

- What I've tried:
  - Obviously the above solution. This doesn't work because myStepper isn't captured, but if you capture it it's not a mover object and can't be passed to AccelStepper.
  - Using an object's function. This doesn't work because object functions have the implicit first parameter this. [See this for more info](https://stackoverflow.com/questions/8865766/get-a-pointer-to-objects-member-function)
  - Making the parameter myStepper static after it's passed in. This doesn't work because it gets over-written on every call to the function.
  - Using std::forward. This would probably work, but I don't think std::forward is defined in ArduinoSTL because I keep getting the error `'forward' is not a member of 'std'`. See the code below:
      - Note, In an attempt to make this work, I upgraded the following folders to `-std=gnu++17` on my ubuntu machine, resulting in `__cplusplus == 201500`:
          - ~/.local/share/umake/ide/arduino/hardware/arduino/avr/platform.txt
          - ~/.local/share/umake/ide/arduino/hardware/hardware/platform.txt

### std::forward attempt

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

    typedef void(*mover)();

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

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

title: Dynamically create functions for AccelStepper that use Adafrut_StepperMotor.oneStep methods?

Answers: 1

body:
I ended up just inheriting AccelStepper, and extending the [
AccelStepper::AccelStepper ( uint8_t interface = AccelStepper::FULL4WIRE,uint8_t pin1 = 2,uint8_t pin2 = 3, uint8_t pin3 = 4, uint8_t pin4 = 5, bool enable = true )](https://www.airspayce.com/mikem/arduino/AccelStepper/classAccelStepper.html#a3bc75bd6571b98a6177838ca81ac39ab) constructor to add my own Adafruit_StepperMotor instance variable and using it in an overridden step0 (which is the only function those callbacks were used in).

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