# Question
Title: Arduino Clone - A request for the USB device descriptor failed
I was working with my arduino clone and that was working well till last night. I was trying to add l298p motor shield and after a few times of testing without any achievement, my PC suddenly did not recognize the arduino. The device status in device manager is :

```
Windows has stopped this device because it has reported problems. (Code 43)
A request for the USB device descriptor failed.

```

What should I do now?? My OS is windows 8.1

# Answer
> 1 votes
You have a cheap Chinese clone with a CH340T USB interface chip.

These are notoriously bad chips. It will have died.

You can fix it (temporarily) by replacing the CH340T with another - though it's anyone's guess how long that'll last.

You can also continue using your board as it is now by either programming the chip directly through ICSP or keep using the bootloader but via an external USB to TTL Serial adapter connected to pins 0/1 + RESET (via a capacitor to DTR) as if it were a "breadboard" Arduino.

That's the price you pay for buying cheap Chinese clones. They may seem like a good idea at the time, but unless you are willing to treat them very much as a throw-away item they are not always the value they appear.

Next time buy a genuine Arduino or an Arduino compatible from a reputable manufacturer.

# Answer
> 4 votes
**Solution for semi-bricked Pro Micro/mini-Leonardo clones:**

The OP's question is ambiguous to as the exact Arduino device in question. My answer applies to the "Pro Micro" or "mini-Leonardo" since these Clones usually use the default Leonardo boot loader, not the modified Sparkfun version.

Note the the Pro Micro doesn't use an external serial to USB chip at all. So the "CH340T USB" argument doesn't apply here. The USB is directly wired to the ATMEGA chip in this case as it has built-in USB 2.0 support.

I've made two projects with these: I gutted an old keypad replaced with a Pro Micro Clone and turned it into a extended keyboard so I could get F13 to F24 keys plus some others, then a custom game foot controller (to 'Q' and 'E' lean in FPS shooters).

Problem, I went to update my Foot controller sketch and after over a year later I forgot my Arduino IDE settings. This time I must have used the wrong setting like "Sparkfun Pro Micro" 3.3.v 8Mhz when your clone is probably like mine a 5v 16Mhz model. When I uploaded the sketch it failed and apparently corrupted the program Flash header or something. The original code was still running (on pedal press my LED lit up) but the device now showed up as "..missing USB device descriptor.." type message in the Windows device manager.

Fear not, it's probably recoverable like it was for me. First of all realize you DON'T set in the Arduino IDE the board to "Spark Fun Pro Micro", simply set it to the default "Arduino Leonardo". That's the right board setting for these clones. The Sparkfun bootloader IS different, as it says on their site. If you uploaded their bootloader then it might work but that's an experiment for another time.

Now you will need to add a reset button to the right hand side of your board (with the micro USB plug pointing up). The pins are next to each other and are clearly labeled. I found a mini-switch just right to fit into the header pins from my parts box. In a pinch you can probably solder two small insulated stripped wires as a makeshift switch, but it might make the following step harder which is timing related.

If you plug your Clone Micro back in, notice if you press the switch the Clone Micro will show back up as a Arduino Leonardo on a COM port for about 8 seconds, then fall back to the bad USB ID thing again.

Now in your Arduino IDE create a NEW sketch. Which will create a minimal program that you'll need to restore your Clone back to working order. Hit the reset switch again and quickly in your IDE preset the "port" to the COM port that shows up. Don't worry it will remember it after the device falls back again.

Now comes the hard part. Unlike a real Sparkfun Micro you can't double tap the reset button for extra time, you only get the 8 seconds period. In the IDE click the "Upload" button, wait about a second, then hit your reset button. If all goes well, you will see the typical flashing programming LED success lights and you will have restored your Clone Micro! This might take a few tries depending on your timing. The thing is to press your reset button slightly after you click the Upload button (or CTRL-U) else you will miss the time frame of the special bootloader reset phase.

Basically this is the directions given here, with a little more details: https://learn.sparkfun.com/tutorials/pro-micro--fio-v3-hookup-guide#troubleshooting-and-faq

---

The OP got some opinionated and pretty toxic responses for an open-source hardware device. Some common sense notes on the morality and ethics of buying Chinese clone devices:

First of all, at least this is not nearly as bad a situation of the Chinese fake chips, arguably the real scourge of the Electronics parts world.

Without spending too much time on the legal ramifications and not being a lawyer, it looks like most of the Sparkfun stuff is CC licensed. Although doubtful the license if for their original or modified software/firmware.

From the Arduino site: "Arduino is an open-source hardware and software company". So the clones are apparently not illegal to buy in the USA (if this is the country of contention).

The reason a lot of people buy the clones is you can buy around three or more of them for the same price of just one Sparkfun Micro. I've been an electronic hobbyist since the late 70's and part of the equation for me is getting a few extras because there is always that chance I'll fry something despite double if not triple checking my wiring. I can make a project plus have some spares for the next time.

I wouldn't use it in anything mission critical, but so far the Clone has been working fine for me as a hobbyist.

These things being said, I'm a big fan of Sparkfun. They are a relatively small USA company that makes fun innovative products with helpful Youtube "how too" videos, etc. I'm all for supporting them.

---
Tags: clones
---


# Question
Title: How to prevent modify library of arduino?
For some reasons of security, I created library for everybody to use, but I don't want people change my library, cause it make device not work. I search around but still not working. Do I need to set password for library or make it unreadable or make it can not modify or another way that you can give the direction ?

P/s: Think like a hacker, I can change library and make an attack to the server from library.

# Answer
> 3 votes
No, you can't do that. How could a library work if it is unreadable?

If you don't want people changing it, don't publish it.

If you publish it you could put a disclaimer on it:

> If you change my library, it may stop working.

---

**(Added to question two days later)**

> P/s: Think like a hacker, I can change library and make an attack to the server from library.

Yes, but, if you distribute the original library, then someone would have to download it, change it, and then attack themselves with it!

And if your library does something to do with servers (you haven't said *what* your library does) then someone could make a similar library, and build the attack code into that. Hacking your particular one wouldn't be required.

My other issue is: If your library is a secret, that is, I can't read its source code, then I might presume that *your* library is where the hack is. At least if people get the source code they can read it and check it.

# Answer
> 3 votes
Later versions of the IDE have the ability to use pre-compiled libraries. This means that the end user only gets the compiled version of your library (a `.a` file) rather than the source code.

Modify your `library.properties` file to include `dot_a_linkage=true`. If you don't have a `library.properties` file you need to make sure you create your library in 1.5.x format.

Then compile your library in the normal way. This will result in a `.a` file somewhere in the build tree which gets linked with your sketch. You need to grab that `.a` file.

Next make a new copy of your library that has just the header file (needed for compilation) and the `.a` file (needed for linking). No `.cpp` files.

Now you in the new `library.properties` file you add `precompiled=true`.

As long as you lay out the files right it should now compile using the precompiled `.a` file.

You can read more about the `library.properties` contents here.

# Answer
> -1 votes
Distribute your library in compiled format. The when code is compiled it's "translated" from "human readable code" to "machine code". Machine code is almost impossible to read and understand without years of experience.

There always is a possibility of decompilation. There are programs called decompilers that change any "machine code" into "human readable code". The resulting code is different then your original code, and there is nothing you can do to prevent decompilation because in the end Arduino has to have that "machine code" to know what operations to execute, and it's impossible to have it encrypterd in any way.

You can make always decompilation more troublesome. There is a procedure called "code obfuscation". You can manually, (or using a specialized code obfuscation software) make the "human readable" code no longer readable by humans. They can add extra variables, extra methods change constants to variables that are generated by completely unrelated parts of code. This will also change machine code, and make the code after decompilation much harder to understand. Unfortunately it will also complicate the machine code and make library run much slower.

Fun Fact!

There exists a competition in code obfustation https://www.ioccc.org/

And this is a valid C code that you can compile and run. https://www.ioccc.org/2014/sinon/prog.c

---
Tags: library
---


title: Powering a Sim800L Module

text:
# Question
Title: Powering a Sim800L Module
I am trying to use a DC power supply. I am thinking whether I can use this power supply to provide power for Sim800L module. After some research, I gathered that the Sim800L module requires a max current of 2A during GPRS transmission at 3.8-4.2 V (4.0 recommended). With the power supply I can easily configure the voltage at 4.0V. My question is: for this setup, do I need a DC-DC Buck Converter as in this one for regulation/step-down (not sure which)?

# Answer
> 1 votes
The lab power supply you linked is serious overkill for your needs. It shouldn't need a separate voltage regulator or buck converter, since I assume that it provdes a voltage and current regulated supply.

A regulated, fixed voltage 4V power supply that can provide 2A is what you want. That will probably cost \< 1/10 of the amount of the lab supply you linked. The challenge is to find a 4V supply. (Most regulated power supplies are either 3.3V or 5V, since those are common voltages for solid state electronics.)

That said, the linear voltage regulators are usually adjustable with a decent voltage range using a resistor.

You could always build your own voltage regulator using a linear voltage regulator rated for 2A, plus a resistor and a couple of capacitors. You could either feed it from an unregulated 6V power supply or use a transformer, bridge rectifier, and capacitor to provide an unregulated DC input to a voltage regulator.

## Edit:

With a little googling I found a few 4V 2A power supplies online. This one, for example:

https://www.alibaba.com/product-detail/US-AC110-220V-To-DC-4V\_62155516966.html?spm=a2700.7724857.normalList.14.a5e64009aUU1ln&s=p

(That link is to a wholesale manufacturer that sells them in volume, but you may be able to find the same supply for single unit sale. A 2A switching 4V supply would meet your needs as well)

---
Tags: arduino-nano, power
---


title: Nth-Light LED Strip power connections

text:
# Question
Title: Nth-Light LED Strip power connections
Based on this question on the Adafruit forum for Nth-Light Narrow LED Flexible Strip Light (https://www.adafruit.com/product/3683) and the image below is it safe to connect from the 12v source + a wire to the Vin (orange wire) or it is better to connect to another DC barrel?

# Answer
If your 12V power supply has enough current to drive your LED strip at its maximum power, plus the Arduino's power supply, plus about 10-20% of "wiggle room" you should be fine. As the LED strip draws spikes of current the voltage from your power supply might bounce around a little, but the Arduino's voltage regulator would be fine with as little as 7.5V input.

Note that your Arduino's voltage regulator will get hot if you use much current from the Ardunio's 5V rails, since it has to regulate 12V down to 5V and the linear regulator on the Arduino converts the extra voltage to heat.
> 1 votes

---
Tags: led, led-strip
---


title: Rotary encoder using interrupt

text:
# Question
Title: Rotary encoder using interrupt
This is my first time working with a rotary encoder and interrupts. I am using a Pro Micro which has interrupt pins at pin0 and pin1. The code below works as expected.

My question: do I need to use an interrupt pin for PinB as well, or can I use any digital pin?

It does not seem to work when I choose PinB = 9, for example.

```
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2); // set the LCD address to 0x27 for a 16 chars and 2 line display

// Used for generating interrupts using CLK signal
const int PinA = 0;

// Used for reading DT signal
const int PinB = 1;

// Used for the push button switch
const int PinSW = 8;

// Keep track of last rotary value
int lastCount = 50;

// Updated by the ISR (Interrupt Service Routine)
volatile int virtualPosition = 50;

// ------------------------------------------------------------------
// INTERRUPT     INTERRUPT     INTERRUPT     INTERRUPT     INTERRUPT
// ------------------------------------------------------------------

void isr ()  {
  static unsigned long lastInterruptTime = 0;
  unsigned long interruptTime = millis();

  // If interrupts come faster than 5ms, assume it's a bounce and ignore
  if (interruptTime - lastInterruptTime > 5) {
    if (digitalRead(PinB) == LOW)
    {
      virtualPosition-- ; // Could be -5 or -10
    }
    else {
      virtualPosition++ ; // Could be +5 or +10
    }

    // Restrict value from 0 to +100
    //virtualPosition = min(100, max(0, virtualPosition));

  }
  // Keep track of when we were here last (no more than every 5ms)
  lastInterruptTime = interruptTime;
}

// ------------------------------------------------------------------
// SETUP    SETUP    SETUP    SETUP    SETUP    SETUP    SETUP
// ------------------------------------------------------------------
void setup() {
  // Just whilst we debug, view output on serial monitor
  //  Serial.begin(9600);

  lcd.init();                      // initialize the lcd

  lcd.backlight();

  // Rotary pulses are INPUTs
  pinMode(PinA, INPUT);
  pinMode(PinB, INPUT);

  // Switch is floating so use the in-built PULLUP so we don't need a resistor
  pinMode(PinSW, INPUT_PULLUP);

  // Attach the routine to service the interrupts
  attachInterrupt(digitalPinToInterrupt(PinA), isr, LOW);

}

// ------------------------------------------------------------------
// MAIN LOOP     MAIN LOOP     MAIN LOOP     MAIN LOOP     MAIN LOOP
// ------------------------------------------------------------------
void loop() {

  // Is someone pressing the rotary switch?
  if ((!digitalRead(PinSW))) {
    virtualPosition = 50;
    while (!digitalRead(PinSW))
      delay(10);
    //    Serial.println("Reset");
  }

  // If the current rotary switch position has changed then update everything
  if (virtualPosition != lastCount) {

    lcd.clear();
    lcd.print(virtualPosition);

    // Keep track of this new value
    lastCount = virtualPosition ;
  }

  //delay(100);
}

```

# Answer
Found my error... on the ProMicro, the pins are not arranged 0, 1, 2, 3, 4, 5 etc instead they arranged 1, 0, 2, 3, 4, 5 etc... On the board I misread TXO and RXI as TX0 and RX1 and just didn't notice it on my pinout sheet.... so I had D0 and D1 swapped. All works well now. Learning more everyday! I appreciate your time...
> 2 votes

---
Tags: interrupt, arduino-pro-micro, rotary-encoder
---


# Question
Title: Is this the right way to blink a character on LCD?
The code is this:

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

LiquidCrystal_I2C lcd(0x27, 16, 2);

unsigned long blinkTime = 0;
int ValueA = 22;
String placeHolder = "  ";

void setup() {
  lcd.begin();
}

void loop() {
  lcd.setCursor(7, 0);
  if (millis() - blinkTime > 2000) {
    lcd.print(ValueA);
    blinkTime = millis();
  }
  if (millis() - blinkTime > 1000) {
    lcd.print(placeHolder);
  }
}

```

The I2C LCD library have a `lcd.blink()` function but it seems that only blinks a "cursor".

The problem with above code is the `placeHolder`, what if `ValueA` gets bigger than 2 digits?

Is there a better way to blink a value on LCD?

# Answer
To blink a number (alternate between the number and empty space(s)), you could try the `BlinkLCD` class in this sketch. It only works with numbers from 0 to 4294967295 or text (`char` array, 16 characters max). It does not work with floating point numbers.

```
// 4540 bytes.
#include <Wire.h>
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27, 16, 2);

class BlinkLCD{

  private:

    byte m_blinkState, m_startPosition, m_dataLength;
    unsigned long m_dataToBlink, m_previousMillis, m_blinkRate;
    char m_text[16 + 1];

  public:

    BlinkLCD(): m_blinkState(0), m_startPosition(0), m_dataLength(0),
                m_dataToBlink(0), m_previousMillis(0), m_blinkRate(500),
                m_text(){}

    void Update(){

      unsigned long m_currentMillis = millis();

      if(m_currentMillis - m_previousMillis >= m_blinkRate){

        byte m_row = 0;
        m_blinkState = !m_blinkState;
        m_previousMillis = m_currentMillis;

        if(m_startPosition > 15){
          m_startPosition -= 16;
          m_row = 1;
        }

        lcd.setCursor(m_startPosition, m_row);

        if(m_blinkState){
          if((unsigned)strlen(m_text) > 0){
            lcd.print(m_text);
          }
          else{
            lcd.print(m_dataToBlink);
          }
        }
        else{
          for(byte i = 0; i < m_dataLength; i++){
            lcd.print(" ");
          }
        }
      }
    }

    void SetBlinkRate(unsigned long blinkRate){
      m_blinkRate = blinkRate;
    }

    void SetNumber(unsigned long dataToBlink){
      m_dataToBlink = dataToBlink;
    }

    void SetLength(byte dataLength){
      m_dataLength = dataLength;
    }

    // LCD top row, columns 0 - 15
    // LCD Bottom row, 16 - 31
    void SetStartPosition(byte startPosition){
      m_startPosition = startPosition;
    }

    void SetText(char text[]){
      strcpy(m_text, text);
    }

};

BlinkLCD TopRowLCD;
BlinkLCD BottomRowLCD;
BlinkLCD BottomRowLCDtext;

void setup(){
  lcd.init();
  lcd.backlight();
  lcd.clear();
  lcd.print("Temperature 35 C");
  lcd.setCursor(0, 1);
  lcd.print("Num = 4294967295");
}

void loop(){

  // Simulate sensor data.
  static byte counter = 35;
  static unsigned long previousMillis = 0;
  unsigned long currentMillis = millis();

  // Update the temperature reading every 2 seconds.
  if(currentMillis - previousMillis >= 2000){
    previousMillis = currentMillis;
    counter++;
    if(counter > 45){counter = 35;}
    lcd.setCursor(12, 0);
    lcd.print(counter);
  }

  // Blink the temperature reading if it's over 40 C.
  if(counter > 40){
    TopRowLCD.SetNumber(counter);
    TopRowLCD.SetStartPosition(12);
    TopRowLCD.SetLength(2);
    TopRowLCD.SetBlinkRate(250);
    TopRowLCD.Update();
  }

  // Blink a number on the second row of the LCD
  // with a default blink rate of 500ms ON, 500ms OFF.
  BottomRowLCD.SetNumber(4294967295);
  BottomRowLCD.SetStartPosition(22);
  BottomRowLCD.SetLength(10);
  BottomRowLCD.Update();

  // Blink some text with at the default blink rate.
  BottomRowLCDtext.SetText("Num");
  BottomRowLCDtext.SetStartPosition(16);
  BottomRowLCDtext.SetLength(3);
  BottomRowLCDtext.Update();

}

```
> 2 votes

---
Tags: c++, lcd
---


# Question
Title: Interrupts arduino interrupting serial comunication
I have problem with communicating VB.Net-Arduino.

It seems the interrupt pause my serial communication line in `void loop() { ... }`. I don't know what to do, and I can't erase interrupts line since I got this code from another site and he said that the interrupt play important role in this code.

So, is there another method to keep interrupts like make a new void in the code? Could you help me, please?

here is the code:

```
//For MEGA 2560

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[] = {
    0, 1, 2, 3, 4, 6, 7, 8, 9, 11, 12, 13, 14, 16, 17, 18, 19, 21, 22,
    23, 24, 26, 27, 28, 29, 31, 32, 33, 34, 36, 37, 38, 39, 40, 42, 43,
    44, 45, 47, 48, 49, 50, 52, 53, 54, 55, 56, 58, 59, 60, 61, 62, 64,
    65, 66, 67, 68, 70, 71, 72, 73, 74, 76, 77, 78, 79, 80, 82, 83, 84,
    85, 86, 87, 89, 90, 91, 92, 93, 94, 96, 97, 98, 99, 100, 101, 102,
    104, 105, 106, 107, 108, 109, 110, 111, 112, 114, 115, 116, 117,
    118, 119, 120, 121, 122, 123, 125, 126, 127, 128, 129, 130, 131,
    132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144,
    145, 147, 148, 149, 150, 151, 152, 152, 153, 154, 155, 156, 157,
    158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170,
    171, 171, 172, 173, 174, 175, 176, 177, 178, 179, 179, 180, 181,
    182, 183, 184, 185, 185, 186, 187, 188, 189, 189, 190, 191, 192,
    193, 193, 194, 195, 196, 197, 197, 198, 199, 200, 200, 201, 202,
    203, 203, 204, 205, 205, 206, 207, 208, 208, 209, 210, 210, 211,
    212, 212, 213, 214, 214, 215, 215, 216, 217, 217, 218, 219, 219,
    220, 220, 221, 221, 222, 223, 223, 224, 224, 225, 225, 226, 226,
    227, 227, 228, 228, 229, 229, 230, 230, 231, 231, 232, 232, 233,
    233, 234, 234, 234, 235, 235, 236, 236, 237, 237, 237, 238, 238,
    238, 239, 239, 240, 240, 240, 241, 241, 241, 241, 242, 242, 242,
    243, 243, 243, 244, 244, 244, 244, 245, 245, 245, 245, 246, 246,
    246, 246, 246, 247, 247, 247, 247, 247, 247, 248, 248, 248, 248,
    248, 248, 248, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249,
    249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249,
    249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249,
    248, 248, 248, 248, 248, 248, 248, 247, 247, 247, 247, 247, 247,
    246, 246, 246, 246, 246, 245, 245, 245, 245, 244, 244, 244, 244,
    243, 243, 243, 242, 242, 242, 241, 241, 241, 241, 240, 240, 240,
    239, 239, 238, 238, 238, 237, 237, 237, 236, 236, 235, 235, 234,
    234, 234, 233, 233, 232, 232, 231, 231, 230, 230, 229, 229, 228,
    228, 227, 227, 226, 226, 225, 225, 224, 224, 223, 223, 222, 221,
    221, 220, 220, 219, 219, 218, 217, 217, 216, 215, 215, 214, 214,
    213, 212, 212, 211, 210, 210, 209, 208, 208, 207, 206, 205, 205,
    204, 203, 203, 202, 201, 200, 200, 199, 198, 197, 197, 196, 195,
    194, 193, 193, 192, 191, 190, 189, 189, 188, 187, 186, 185, 185,
    184, 183, 182, 181, 180, 179, 179, 178, 177, 176, 175, 174, 173,
    172, 171, 171, 170, 169, 168, 167, 166, 165, 164, 163, 162, 161,
    160, 159, 158, 157, 156, 155, 154, 153, 152, 152, 151, 150, 149,
    148, 147, 145, 144, 143, 142, 141, 140, 139, 138, 137, 136, 135,
    134, 133, 132, 131, 130, 129, 128, 127, 126, 125, 123, 122, 121,
    120, 119, 118, 117, 116, 115, 114, 112, 111, 110, 109, 108, 107,
    106, 105, 104, 102, 101, 100, 99, 98, 97, 96, 94, 93, 92, 91, 90,
    89, 87, 86, 85, 84, 83, 82, 80, 79, 78, 77, 76, 74, 73, 72, 71, 70,
    68, 67, 66, 65, 64, 62, 61, 60, 59, 58, 56, 55, 54, 53, 52, 50, 49,
    48, 47, 45, 44, 43, 42, 40, 39, 38, 37, 36, 34, 33, 32, 31, 29, 28,
    27, 26, 24, 23, 22, 21, 19, 18, 17, 16, 14, 13, 12, 11, 9, 8, 7, 6,
    4, 3, 2, 1, 0
};

#define toggle 7

int sw;
int nilaiVB;
int potvolt = A1;                //Pengatur Tegangan
int potfreq = A2;                //Pengatur Frequency

float potvoltval;
float potfreqval;
float DataVolt;
float DataFreq;
float A;
float F;

String inputString = "";         // a String to hold incoming data
boolean stringComplete = false;  // whether the string is complete
String In_1;
String In_2;

int Val1 = 0;
int Val2 = 0;

void setup() {
    Serial.begin(9600);
    inputString.reserve(200);

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

    cli();                            // stop interrupts
    TCCR0A = 0;                       //reset nilai
    TCCR0B = 0;                       //reset nilai
    TCNT0 = 0;                        //reset nilai
    //0b : menulis bits dalam binary
    TCCR0A = 0b10100001;              //phase correct pwm mode
    TCCR0B = 0b00000001;              //tidak ada prescaler

    TCCR2A = 0;                       //reset nilai
    TCCR2B = 0;                       //reset nilai
    TCNT2 = 0;                        //reset nilai
    //0b : menulis bits dalam binary
    TCCR2A = 0b10100001;              //phase correct pwm mode
    TCCR2B = 0b00000001;              //tidak ada prescaler

    TCCR3A = 0;                       //reset nilai
    TCCR3B = 0;                       //reset nilai
    TCNT3 = 0;                        //reset nilai
    //0b  : menulis bits dalam binary
    TCCR3A = 0b10100001;              //phase correct pwm mode
    TCCR3B = 0b00000001;              //tidak ada prescaler

    TCCR1A = 0;                       //reset nilai
    TCCR1B = 0;                       //reset nilai
    TCNT1 = 0;                        //reset nilai
    OCR1A = 509;                      // compare match value
    TCCR1B = 0b00001001;  //WGM12 bit is 1 for CTC mode and no prescaler

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

    sei();                            // enable interrupts
}

// interrupt mulai ketika timer 1 cocok dengan OCR1A
ISR(TIMER1_COMPA_vect) {

    //=========================Phase A================================//

    if (i > 629 && OK == 0) {   // nilai akhir dari sample untuk pin 13
        i = 0;                  // mulai dari nilai awal sample
        OK = 1;                 // mengaktifkan pin 4
    }

    if (i > 629 && OK == 1) {   // nilai akhir dari sample untuk pin 4
        i = 0;                  // mulai dari nilai awal sample
        OK = 0;                 // mengaktifkan pin 13
    }

    x = round(A*sinPWM[i]); // nilai x berasal dari sample dan i berindex 0
    i = i+F;                    // ke posisi selanjutnya dari sample
    if (OK == 0) {
        OCR0B = 0;                      //pin 4 0
        OCR0A = x; //pin 13 memulai pembacaan sample
    }

    if (OK == 1) {
        OCR0A = 0;                      //pin 13 0
        OCR0B = x; //pin 4 memulai pembacaan sample
    }

    // jika nilai i mencapai 209, maka phase kedua akan dimulai
    if ((i >= 418) || OK1 == 1) {
        OK1 = 1;                  //mempertahankan if function

        //=========================Phase B============================//

        if (j > 629 && OK2 == 0) {  // nilai akhir dari sample untuk pin 10
            j = 0;                  // mulai dari nilai awal sample
            OK2 = 1;                // mengaktifkan pin 9
        }

        if (j > 629 && OK2 == 1) {  // nilai akhir dari sample untuk pin 9
            j = 0;                  //mulai dari nilai awal sample
            OK2 = 0;                // mengaktifkan pin 10
        }

        y = round(A*sinPWM[j]); // nilai y berasal dari sample dan i berindex 0
        j = j+F;                    // ke posisi selanjutnya dari sample
        if (OK2 == 0) {
            OCR2B = 0;              // pin 9 0
            OCR2A = y;              // pin 10 memulai pembacaan sample
        }

        if (OK2 == 1) {
            OCR2A = 0;              // pin 10 0
            OCR2B = y;              // pin 9 memulai pembacaan sample
        }
    }

    // jika nilai j mencapai 209, maka phase ketiga akan dimulai
    if ((j>= 418) || OK3 == 1) {
        OK3 = 1;                    // mempertahankan if function

        //=========================Phase C============================//

        if (k > 629 && OK4 == 0) {  // nilai akhir dari sample untuk pin 5
            k = 0;                  // mulai dari nilai awal sample
            OK4 = 1;                // mengaktifkan pin 2
        }

        if (k > 629 && OK4 == 1) {  // nilai akhir dari sample untuk pin 2
            k = 0;                  // mulai dari nilai awal sample
            OK4 = 0;                // mengaktifkan pin 5
        }

        z = round(A*sinPWM[k]); // nilai z berasal dari sample dan i berindex 0
        k = k+F;                    // ke posisi selanjutnya dari sample
        if (OK4 == 0) {
            OCR3B = 0;              // pin 2 0
            OCR3A = z;              // pin 5 memulai pembacaan sample
        }

        if (OK4 == 1) {
            OCR3A = 0;              // pin 5 0
            OCR3B = z;              // pin 2 memulai pembacaan sample
        }
    }
}

void loop() {
    sw = digitalRead(toggle);

    if (sw == 0) { //    VB
        if (stringComplete) {
            if (inputString.substring(0, 4) == "VOLT") {
                In_1 = inputString.substring(4);
                Val1 = In_1.toInt();
                A = Val1/1023; // Formula Pengontrolan Tegangan
                Serial.println(Val1);
            }
            if (inputString.substring(0, 4) == "FREQ") {
                In_2 = inputString.substring(4);
                Val2 = In_2.toInt();
                F = map(Val2, 1023, 0, 0, 50);// Formula Pengontrolan Frequensi
            }

            inputString = "";
            stringComplete = false;
        }
    }
    else if (sw == 1) { // Potensiometer
        potvoltval = analogRead(potvolt);
        A = potvoltval/1023; // Formula Pengontrolan Tegangan

        potfreqval = analogRead(potfreq);
        F = map(potfreqval, 1023, 0, 0, 50);// Formula Pengontrolan Frequensi
    }
}

void serialEvent() {
    while (Serial.available()) {
        // get the new byte:
        char inChar = (char) Serial.read();
        // add it to the inputString:
        inputString += inChar;
        // if the incoming character is a newline, set a flag so the
        // main loop can do something about it:
        if (inChar == '\n') {
            stringComplete = true;
        }
    }
}

```

And here are the interrupts position:

And i got the code from this site

And Here is my VB code

```
Public Class Form1

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    Try
        Me.CenterToParent()
        SerialPort1.PortName = "COM4"
        SerialPort1.BaudRate = 9600
        SerialPort1.Open()
        Timer1.Start()
        SerialPort1.Write("VOLT" & TrackBar1.Value & Chr(10))
        SerialPort1.Write("FREQ" & TrackBar2.Value & Chr(10))
    Catch ex As Exception
        MsgBox(ex.Message, MessageBoxIcon.Error, "Error Message")
        Me.Close()
    End Try
End Sub

Private Sub Form1_Closed(sender As Object, e As EventArgs) Handles Me.Closed
    SerialPort1.Close()
End Sub

Private Sub TrackBar1_Scroll(sender As Object, e As EventArgs) Handles TrackBar1.Scroll
    Try
        SerialPort1.Write("VOLT" & TrackBar1.Value & Chr(10))
    Catch ex As Exception
        MsgBox(ex.Message, MessageBoxIcon.Error, "Error Message")
    End Try
End Sub

Private Sub TrackBar2_Scroll(sender As Object, e As EventArgs) Handles TrackBar2.Scroll
    Try
        SerialPort1.Write("FREQ" & TrackBar2.Value & Chr(10))
    Catch ex As Exception
        MsgBox(ex.Message, MessageBoxIcon.Error, "Error Message")
    End Try
End Sub
End Class

```

And the design as well

# Answer
> 0 votes
Since the ISR being too long seems to be your main problem, I will address the possibility to set a flag in the ISR. See this code example (which is not a complete compilable example, only code to show the principle):

```
volatile byte flag = 0;

ISR(TIMER1_COMPA_vect) {
    flag = 1;
}

void loop(){
    if(flag){
        flag = 0; // resetting the flag for the next execution
        //execute the code here, that was previously in the ISR
    }
}

```

First a flag variable is declared as volatile. This tells the compiler, that the value of this variable can change at any time and that the compiler cannot optimize it by using a cached value or other optimizations. This is always required, when you access a variable both in ISR's and the normal code.

In the actual ISR this flag is simply set to `1`. This takes very short time, so that no other interrupt (for example for Serial) will be blocked by it.

Then in our `void loop()` we are checking if the flag has a value, that isn't zero (every value other than zero will evaluate as `true`, so we don't need a comparison operator here). If yes, we first reset the flag to zero, so that another interrupt can set it again to 1. Then we are executing the other code, that was previously in your ISR. Since it now runs in normal code, it will not block Serial interrupts from happening.

---

"The ISR is too long" can also mean, that it is happening too often. Juraj already stated in his comment, that the interrupt happens "every 509 clock ticks". That is not very much. You can increase the time between 2 consecutive timer interrupts by using a prescaler. As doing just this would reduce the frequency of your output sinus wave, you would need to do some calculations, maybe only using every forth or so array element of the sinus wave. With this you are loosing precision in time, but you gain more computation time to do other things.

---

In general you always have to do a trade-of. The longer the code runs, that should be executed on a timer interrupt, the less precision will be possible with it. The code should always run considerable shorter, that the time between two consecutive interrupts.

Your code is not really understandable, since you didn't use speaking variable names and your comments are not written in english. From the structure I would guess, that it can be strongly optimized by you to execute shorter, but without understanding what the code really should do, that is only wild guessing.

---
Tags: arduino-mega, interrupt, serial-data, visualstudio
---


# Question
Title: Will Funduino Joystick Shield work on a Mega?
I am trying to get a Funduino Joystick Shield working with an Arduino Mega and I need to use the WiFi capability. The specs I have found for the Funduino (see https://protosupplies.com/product/funduino-joystick-shield-v1-a/) use the standard UNO pins for the RF24: 9..13, The Mega uses pins in the high 40s for this interface. Is there a way to make this work?

# Answer
> 1 votes
The shield will work on Mega, except of the SPI connection for the nRF24L01 connector. The shield expects SPI on pins 11, 12, 13 and Mega has them on 50, 51, 52. Other shields use the SPI pins on the ICSP header to have compatibility with different boards. This shield doesn't connect to the ICSP header.

You can wire the nRF24L01 to SPI pins on 50, 51, 52.

---
Tags: arduino-uno, arduino-mega, wifi
---


title: What is "tCAN" in codes of CAN bus?

text:
# Question
Title: What is "tCAN" in codes of CAN bus?
I'm new to Arduino and CAN bus. I'm studying some code examples which contain "tCAN message". My guess it defines a class for of CAN messages. I did a lot of search but found no information on it except for sample codes. Can anyone help me out. Thank you!

Some code from the example project:

```
void activateCAN()
{
 //***PREPARE MESSAGE***//
    tCAN message_act;
    message_act.id = 0x750;
    message_act.header.rtr = 0;
    message_act.header.length = 8;
    message_act.data[0] = 0x00;
    message_act.data[1] = 0x00;
    message_act.data[2] = 0x00;
    message_act.data[3] = 0x00;
    message_act.data[4] = 0x00;
    message_act.data[5] = 0x00;
    message_act.data[6] = 0x00;
    message_act.data[7] = 0x00;

    mcp2515_bit_modify(CANCTRL, (1 << REQOP2) | (1 << REQOP1) | (1 << REQOP0), 0);
    mcp2515_send_message(&message_act); //SEND MESSAGE
}
//******CAN ACTIVATION*****ENDS****//

```

# Answer
> 2 votes
`tCAN` will be a `struct` that defines the structure of the CAN message being sent. The name `tCAN` is not a standard and will have been chosen by the author of the library you are using. At a guess it's using a variant of Hungarian Notation, and the `t` prefix means `type` \- so it's probably been `typedef`'d from a struct to a type name.

I am not familiar with CAN, but if there are standard message formats this struct will correspond with one of them. You can find the actual structure within the header file for your chosen library (or maybe in the example sketch code itself?).

# Answer
> 2 votes
`tCAN` here is a `struct` that defines a CAN *frame* to be sent over the network.

https://en.m.wikipedia.org/wiki/CAN\_bus#Frames

There are several types of frames, standard, extended, and FD (flexible data).

The tables in the linked Wikipedia article describe the physical protocol. The struct won’t have a corresponding field for every section of the protocol, because the library will take care of setting the constant or calculatable things, like the CRC and End of Frame. You just have to set the relevant details, like ID, (maybe) data length and the data itself.

If you have trouble, check your baud rates and ensure you’re sending the expected kind of frame. Most hobbyist will use standard frames, but many industrial grade pieces of equipment will use Extended or FD frames.

---
Tags: arduino-uno, can-bus
---


# Question
Title: What are the better options to the basic Arduino Serial Plotter?
Arduino Serial Plotter does not allow analysis or saving of data. What are the best serial data graphing software (preferably free, but i don't mind if it's paid as long as it's better than the bare-bones Arduino Serial Plotter)?

1. It should work well with Arduino
2. It should allow plotting several variables on the same graph
3. Allow exporting data to CSV so i can show it in Excel.

# Answer
> 4 votes
Custom devices require custom solutions.

I suggest using Python (don't be scared).

This tutorial shows us how to read data from serial and save it to .csv file. You don't have to use a file. For example you can modify it to use an in memory list, and save just values from last 30 seconds. You can also read several values, and not just one.

```
import serial
import time
import csv

ser = serial.Serial('/dev/ttyACM0')
ser.flushInput()

while True:
    try:
        ser_bytes = ser.readline()
        decoded_bytes = float(ser_bytes[0:len(ser_bytes)-2].decode("utf-8"))
        print(decoded_bytes)
        with open("test_data.csv","a") as f:
            writer = csv.writer(f,delimiter=",")
            writer.writerow([time.time(),decoded_bytes])
    except:
        print("Keyboard Interrupt")
        break

```

This tutorial (and this one) shows you how very quickly to show a sophisticated plot of the data you collected. You can even make a plot that shows several graphs and updates in real time.

```
import matplotlib.pyplot as plt
plt.plot([1,2,3,4])
plt.ylabel('some numbers')
plt.show()

```

Don't be scared it's not black magic. It just takes few days to understand how things work.

---
Tags: arduino-uno, serial
---


title: Arduino Timer0 Piggyback

text:
# Question
Title: Arduino Timer0 Piggyback
As described here https://learn.adafruit.com/multi-tasking-the-arduino-part-2/timers

I use timer 0 to get my own timer with a milliseconds resolution.

It is setup like this:

```
void setup (void)
{
    ...
    cli();
    OCR0A  = 0xAB;
    TIMSK0 |= (1 << OCIE0A);
    sei();
    ...
}

```

The value 0xAB is chosen randomly and should not affect the behaviour.

The interrupt handler looks like this:

```
ISR(TIMER0_COMPA_vect)
{
    if (myTimer != 0)
        myTimer--;
    return;
}

```

This works just OK but having a closer look at the actual timing values using millis() I've found that the timer values given by this ISR are about 2-3% too long.

According to adafruit.com this method should exactly follow the built-in millis() timer of the Arduino. In my program there are no other interrupts active. There are some Serial.print() outputs, maybe they affect the timing? The solution I've found looks like this:

```
ISR(TIMER0_COMPA_vect)
{
    static unsigned long timeLast;

    unsigned long timeNow = millis();
    uint8_t timeDiff = (uint8_t)(timeNow - timeLast);
    timeLast = timeNow;

    if (myTimer != 0)
        myTimer -= timeDiff;

    return;
}

```

Instead of simply decrementing the timer, the timer value is decreased by the actual amount of time since the last call of the ISR.

With this my timer follows exactly the millis(). But why doesn't the first approach give an exact timing? Apparently there are some cases where the time between calls of the ISR is not 1ms but 2ms.

# Answer
The Arduino core configures Timer 0 for a period of 1,024 µs. Your ISR will then be called at very regular intervals, and is a good place to have timing-related code. You just have to keep in mind that the unit of time is not one millisecond, but 1.024 ms.

If this “weird” unit bothers you, then you could do what the Arduino timing ISR does: keep track of how late, relative to a 1 ms period, you are getting. When you notice you are 1 ms late, count one extra millisecond.
> 3 votes

---
Tags: timers, avr, millis, isr
---


# Question
Title: Can I prevent the Stepper library from holding the motor?
I'm using the Stepper library to control a single stepper motor. When the Arduino is not running the motor it is holding the motor shaft in place. For my application, this is very wasteful and puts unnecessary strain on the motor.

Is the Stepper library supposed to do this or is something else up with my circuit? Can this behavior be overridden?

# Answer
use disable output class in accelstepper library. http://www.airspayce.com/mikem/arduino/AccelStepper/
> 4 votes

# Answer
Stepper library has nothing to do with this. What **holds** your motor are those **GND**s or **0 Volt**s applied to control pins of your Stepper motor.

What you are looking for is UL2003A. The way ULN2003A works is solution to your problem.

Assuming your stepper is unipolar, Here is a complete tutorial on how to use Stepper motor with UNL2003A.
> 0 votes

# Answer
The ability to release all the stepping motor coils depend on the hardware and software used. For example, the Adafruit.com hardware and software has this function to release all the stepping motor coils. Investigate their approach and determine if you can contribute to the library you are using by porting this feature. Also investigate if this feature is not (serendipitously) already part of the library you are using. For instance, it is not unreasonable to expect the library you are using to return Atmel pins to a passive input state (which, depending on the hardware, may release the stepper) when you destroy the instance of the stepper library class.
> 0 votes

# Answer
```
//for all pins used for controlling stepper motor assign all of them LOW

#include<Stepper.h>
const int stepsPerRevolution = 200;
Stepper myStepper(stepsPerRevolution, 10, 11,12,13);

void setup() {
  myStepper.setSpeed(30);

Serial.begin(9600);
}

void loop(){

 Serial.println("clockwise");
  myStepper.step(stepsPerRevolution*5);
  delay(300);
digitalWrite(10,LOW);
  digitalWrite(11,LOW);
digitalWrite(12,LOW);
digitalWrite(13,LOW);

}

```
> 0 votes

---
Tags: arduino-uno, library, stepper
---


# Question
Title: Which kind of diodes I should use in buttons/keys matrix input? (Making gaming keyboard)
When making matrix input of NxM columns/rows with push buttons, there should be a diode next to each button to prevent "ghosting" and able read many keys pressed together correctly. There is a lot of pictures everywhere.

My problem is, **which diodes** to use and also **why** this type (or why it does not matter).

---

More details:

I would use 5 V Arduino (ATmega32U4), datasheet states for input low voltage max 0.3Vcc, which is 1.5 V and minimal high input voltage 0.7Vcc = 3.5 V and pullups at least 1.5 kΩ (Vcc-0.4 V / 3 mA)

I would like to use 74HC138 3-to-8 decoder for addressing, which makes one of 8 outputs Low (max 0.1 V), while other 7 High (min 4.5 V) and drive the Arduino inputs Low, if button is pressed.

To be on safe side, I would like also add resistors on each pin to make sure, that bad programming (make some input pin OUTPUT and HIGH and pressing key connect it to LOW output on other side) could not damage the circuits, so it looks like 5 V/20 mA = 250 Ω (and I will hope it would not hit more pins, so I would not consider total port/chip limitations).

In typical case it would be **5 V** \- 1.5 kΩ pullup - **input** \- 250 Ω - wires and button - **diode** \- 250 Ω - **0.1 V** for selected line.

If the diode would be theoretical and ideal, then there is (in the worse case) promised to be max 1.2 V on Input, which is slightly less then "maximal low" voltage (1.5 V) and like 5V/2 kΩ = 2.5 mA current.

But the diode is not ideal and have some forward voltage, which make the case even worse.

So I probably cannot use simply `INPUT_PULLUP` (as it may work by luck, but is not guaranted by specs) but I need to use `INPUT` and set some higher pullup there to "burn" more volts on it to compensate for the diode.

The Input Current for each pin is 10 µA (in or out) and I heard some recommendation, that on resistor divider should be the total current 10x more, then the input current, so it would mean 100 µA = 0.1 mA

The pullup then could go as high as ((5 V - 0.1 V - Vf)/0.1 mA ) - 500 Ω If the forward voltage would be 1 V (wild guess) it would go to something like 38.5 kΩ pullup and 1.15 V on input. The maximal Vf forward voltage would be like 1.35 V (at 0.1 mA), pullup 35 kΩ and 1.5 V on input.

---

My problem is, that many online Arduino schemes works just because Arduino usually work good even in way out-of-spec situations, and suggested values cames from what the author just randomly had at hands and it worked by pure luck and maybe another hidden factors, as parasite capacity of breadboard or so. So I want to uderstand, **why** I should choose some parts and how to came to such conclusions by myself.

I want to make reliable projects, not just projects, which works most of the time and fail only occasionally.

---

* It is the right path, how to compute it or did I some mistake?
* I want use scanning frequency at least 800 Hz (8 lines and results 100x per second) or more (like 10 kHz to be done fast and to have more time to spend with other tasks, like sending USB packets, computing macros, managing light effects etc)
* which common and cheap SMD diodes I should buy?
    + reverse voltage over 5 V, current over 100 mA, switch frequency over 10 kHz, forward voltage under 1.3 V at 0.1 mA (rather much less to have safe gap from limits)
    + really common cheap model, so everybody would know it and so I could use it everywhere in similar settings without thinking ( or even computing like in previous section)
    + preferably what you (and everyone else and his dog too) use for such cases
    + I would like to order from AliExpress, so rather higher margin for guaranteed values
    + preferably to fit on 0.1 inch spaced universal PCB (0805 SMD LEDs are really easy to solder there (so rather not smaller than that), but it may be twice the size too or something like that)
    + I would buy like some hundreds of such diodes to have them ready on hands and I will probably make more similar projects over time for me and my friends

Thanks for all comments and suggestions

# Answer
> 2 votes
When I've used a keypad matrix I've wired it up like this:

I used 1N4148 SMD diodes which I bought cheaply. I cut the traces on my cheap board that I had purchased from Jaycar and soldered them in like this:

The dot is the cathode (there is a line etched on my diodes at the cathode end).

The 10k resistors effectively turn the columns into pull-ups, therefore there is no danger of bad code damaging the Arduino or anything else.

Example code to scan the matrix:

```
// Keypad_Decoder
//
// Author: Nick Gammon
// Date: 17th February 2018

// Outputs to Serial in the format: 0b1nnnnnnn for a key down and 0b0nnnnnnn for a key-up
//            nnnnnnn will be the current row/column combination
//            Also every HEARTBEAT_TIME outputs 0xFF if all keys are up (heartbeat)

#include <limits.h>     /* for CHAR_BIT */

const byte ROWS = 4;
const byte COLS = 4;
const bool ENABLE_PULLUPS = true;  // make false if you are using external pull-ups
const unsigned long DEBOUNCE_TIME = 10;     // milliseconds
const unsigned long HEARTBEAT_TIME = 2000;  // milliseconds
const bool DEBUGGING = false;               // make true for human-readable output

// define here where each row and column is connected to
const byte rowPins [ROWS] = {6, 7, 8, 9}; //connect to the row pinouts of the keypad
const byte colPins [COLS] = {2, 3, 4, 5}; //connect to the column pinouts of the keypad

// See: http://c-faq.com/misc/bitsets.html

#define BITMASK(b) (1 << ((b) % CHAR_BIT))
#define BITSLOT(b) ((b) / CHAR_BIT)
#define BITSET(a, b) ((a)[BITSLOT(b)] |= BITMASK(b))
#define BITCLEAR(a, b) ((a)[BITSLOT(b)] &= ~BITMASK(b))
#define BITTEST(a, b) ((a)[BITSLOT(b)] & BITMASK(b))

// number of items in an array
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))

// total number of keys
const byte TOTAL_KEYS = ROWS * COLS;

// remember previous setting of each key
char lastKeySetting [(TOTAL_KEYS + CHAR_BIT - 1) / CHAR_BIT];  // one bit each, 0 = up, 1 = down
unsigned long lastKeyTime [TOTAL_KEYS];       // when that key last changed
unsigned long lastHeartbeat;                  // when we last sent the heartbeat

void setup ()
{
  Serial.begin (115200);
  while (!Serial) { }  // wait for Serial to become ready (Leonardo etc.)

  // set each column to input-pullup (optional)
  if (ENABLE_PULLUPS)
    for (byte i = 0; i < COLS; i++)
      pinMode (colPins [i], INPUT_PULLUP);

}  // end of setup

void loop ()
  {
  byte keyNumber = 0;
  unsigned long now = millis ();  // for debouncing

  // check each row
  for (byte row = 0; row < ROWS; row++)
    {
    // set that row to OUTPUT and LOW
    pinMode (rowPins [row], OUTPUT);
    digitalWrite (rowPins [row], LOW);

    // check each column to see if the switch has driven that column LOW
    for (byte col = 0; col < COLS; col++)
      {
      // debounce - ignore if not enough time has elapsed since last change
      if (now - lastKeyTime [keyNumber] >= DEBOUNCE_TIME)
        {
        bool keyState = digitalRead (colPins [col]) == LOW; // true means pressed
        if (keyState != (BITTEST (lastKeySetting, keyNumber) != 0)) // changed?
          {
          lastKeyTime [keyNumber] = now;  // remember time it changed
          // remember new state
          if (keyState)
            BITSET (lastKeySetting, keyNumber);
          else
            BITCLEAR (lastKeySetting, keyNumber);
          if (DEBUGGING)
            {
            Serial.print (F("Key "));
            Serial.print (keyNumber);
            if (keyState)
              Serial.println (F(" down."));
            else
              Serial.println (F(" up."));
            }  // if debugging
          else
            Serial.write ((keyState ? 0x80 : 0x00) | keyNumber);
          }  // if key state has changed
        }  // debounce time up
      keyNumber++;
      } // end of for each column

    // put row back to high-impedance (input)
    pinMode (rowPins [row], INPUT);
    }  // end of for each row

  // Send a heartbeat code (0xFF) every few seconds in case
  // the receiver loses an occasional keyup.
  // Only send if all keys are not pressed (presumably the normal state).
  if (now - lastHeartbeat >= HEARTBEAT_TIME)
    {
    lastHeartbeat = now;
    bool allUp = true;
    for (byte i = 0; i < ARRAY_SIZE (lastKeySetting); i++)
      if (lastKeySetting [i])
        allUp = false;
    if (allUp)
      {
      if (DEBUGGING)
        Serial.println (F("No keys pressed."));
      else
        Serial.write (0xFF);
      } // end of all keys up
    } // end if time for heartbeat
  } // end of loop

```

---

Speedwise, I measured around 300 µs for doing a scan with no keys pressed. If that time seems a bit long, you could always do a time check, and scan every 5 ms or so.

I have a post about all this on my forum. In that post I also mention a library that handles N-key rollover, so you can detect multiple keys being pressed at the same time. For example, you could use A/B/C/D on the keypad as "shift" keys, so that A+1 meant something different than just 1.

---

Matrix from the front:

---

> My problem is, which diodes to use and also why this type (or why it does not matter).

I don't think the exact diode is critical in this case. If this was a very high speed application, then a diode with fast switching might be required. If it was high voltage then a higher-spec diode might be required. In some cases the reverse voltage might apply. In this particular case, since we are dealing on/off at logic levels, I don't think much of this matters, although the switching speed might to a certain extent, however I am guessing from empirical observations that the speed of the 1N4148 is fast enough.

Also see: Wikipedia - 1N4148:

> The 1N4148 is useful in switching applications up to about 100 MHz with a reverse-recovery time of no more than 4 ns.

# Answer
> 0 votes
Solution: 1N4148 diode

generally if you want connect diode to Arduino pin, use this one as it would be OK under nearly any normal use

* 75 V reverse voltage (much more than 5V allowed there)
* 1 V forward voltage at 10 mA (less at lower current)
* 10 mA recommended current (destroys at 1 A 1 sec pulse) (and you do not want more then 10 mA anyway)
* usable up to 100 MHz (so using digitalRead/digitalWrite and some logic you are way slower anyway)
* super extra common for long time (even 10 years ago was considered "classical") and still actual (so when you get old, it would still be here)
* dirty cheap (buy few hundreds just now and you do not need care anymore)

---
Tags: arduino-leonardo, hardware, keyboard
---


title: Variable declaration inside main loop

text:
# Question
Title: Variable declaration inside main loop
In the past I declared variables inside the main loop which worked just fine. In a new project I did the same:

```
void loop(void)
{
    uint8_t counter;
    ....
    if (buttonPress)
        counter = 0;
    ...
    if (someCondition == true)
    {
        Serial.println(counter);
        counter++
    }
}

```

But then the output of the variable *counter* shows that for some reason the counter variable is reset to 0 instead of counting up. This happens even after the button is released.

The scope of the variable *counter* is the main loop and I just assumed that it will keep its value and count up.

What might be the reason for this variable to reset to 0? Is it that other functions are called within the main loop? Is it that an interrupt handler is called every now and then?

The solution I've found is to declare the variable as static:

```
static uint8_t counter;

```

Then it increments as expected.

Even though I've found a solution I'd really like to understand what the problem with my first approach was.

# Answer
Michael's answer was good, as usual. Let me give you some more background though:

In C/C++ (And in most modern languages) variables have a "scope", or an area where they are defined.

Global scope:

Variables declared at the top level of your program have global scope, and exist for the life of your program. These variables are usually created on the .data or .bss sections.

Local scope

Variables declared inside a function have local scope. Unless they are `static`, they get created when the function is entered, and get discarded when the function exits. These variables are created on the stack as part of the function's stack frame.

Object scope

In C++ and other object-oriented languages, instances of objects have their own scope, "instance variables". Every instance of an object has its own set of instance variables. (Think of cars, and a car radio. You and I might own the exact same model of car, but if I set my car's radio station and you set your car's radio to a different station, each instance of the car has a different setting for the radio station.)

Static variables:

Static variables are variables that are declared "statically." That means that they are only created once and persist, even if they are declared inside a scope like a function or a class instance. These have the lifespan of a global variable but can be declared inside a function or in an object.

---

Loop is a function, so variables declared inside of `loop()` are local variables. They get created anew every time the function is called, and discarded every time the function exits.
> 4 votes

# Answer
Your code has a couple of bugs. First you don't initialize counter before using it. Second the variable 'counter' has limited scope, it has no definition when loop() exits. If you want this variable to stay around declare it as static.

Both bugs corrected e.g.:

```
void loop(void)
{
    static uint8_t counter = 0;
    ....
    if (buttonPress)
        counter = 0;
    ...
    if (someCondition == true)
    {
        Serial.println(counter);
        counter++
    }
}

```

Note: Initializing counter to 0 only happens once, on subsequent calls to loop() counter will retain it's previous value.
> 2 votes

# Answer
The problem is that you declare a new variable. So even though the name is the same, the local variable is destroyed at the end of the loop and recreated at the beginning.

Actually, there is no good solution:

* Global variables are best to be avoided. They can be seen as 'singleton's', e.g. variables that are needed at many places in the code and have only one occurrence.
* As you found out, static solves the problem. I would use this option, although personally I'm not a fan of static variables.
* Another way is to put the loop in a while, so you get:

void loop(void) { uint8\_t counter = 0; // Always initialize variables while (true) { // Your code } }

This will work too, as your counter is only initialized once, however the loop is already (internally) a while loop, so you have two.
* A much better way but more extra work, is to create a C++ class, where counter can be a class variable, which is local for that class (which could still be a singleton). Of course this is only true when the counter variable is belonging logically to that class, if it is not, just keep it a global variable (updated after Edgar Bonet's remark).
> 0 votes

---
Tags: programming, c, code-review
---


title: Make a set LED dimming schedule?

text:
# Question
Title: Make a set LED dimming schedule?
I'm trying to made the LED's go from minimum brightness to maximum brightness and back to minimum in 2.55 seconds.

I really don't know where to begin. I have the following basic code for making it blink simultaneously, but how do I make it cycle through during the time I want:

```
int led = 10;           //the PWM (tilde) pin the LED is attached to

int led2 = 9;

int led3 = 11;

int brightness = 0;    //how bright the LED is

int delaytime = 25;

int fadeAmount = 5;    //how many points to fade the LED by

//the setup routine runs once you press the reset:

void setup() {

  // declare pins to be an output:

  pinMode (led, OUTPUT);

  pinMode (led2, OUTPUT);

  pinMode (led3, OUTPUT);

}

//the loop routine runs over and over again forever:

void loop() {

  // set the brightness of pin 10:

  analogWrite (led, brightness);

  analogWrite (led2, brightness);

  analogWrite (led3, brightness);

  //change the brightness for next time through the loop:

  brightness = brightness + fadeAmount;

  //reverse the direction of the fading at the ends of the fade:

  if (brightness <= 0 || brightness >= 255) {

    fadeAmount = -fadeAmount;

  }

//wait for set milliseconds to see the dimming effect

delay (delaytime);

}

```

\**bonus: the next part includes making each LED go on its own schedule so the more thoroughly you can explain this first the better I can attempt the next part.

THANK YOU!

# Answer
> 0 votes
The way to go is the non-blocking coding style, that can be found in the `BlinkWithoutDelay` example, that comes with the Arduino IDE. There you use `millis()` to measure time. You save a timestamp for every LED and in every execution of the `void loop()` you check, if enough time has passed since the last timestamp. You have to do this for every LED.

Since this coding style has been explained numerous times through the internet and on this site, I will not go more into detail. You can google the rest, understand, how that style works and then transfer that to your case.

# Answer
> 1 votes
Have a look at these instructables...

One does the gradual fading of an led (on and off) via PWM: LED lighting in a staircase.

The second deals with the "there own schedule" bit - which I assume means cycle on and off independently of one another.: cooperative multitasking.

Disclaimer.. they are my instructables posts, but they do address the question. There are also several libraries available for running "timed tasks" if you prefer an alternative solution.

Here is an practical example that should deal with both aspects of your question (hopefully it will stem the tide of negative feedback)...

It should work on an UNO or any other Arduino with PWM on pins 3, 5 and 6. Of course you are free to adjust the pins to suit your needs (including adding more or taking some out).

```

int pwmPin[] = {3, 5, 6 };        // Pins that are being used for PWM.
int pwmValue [] = { 0, 0, 0};     // Initial value of PWM duty cycle in the range 0 to 255.
int pwmIncrement[] = {1, 1, 1};   // The value by which the PWM will be incremented at each step.
                                  // NB, this can not be zero but you can start with negative numbers if you wish.
unsigned int pwmDelay[] = { 20, 30, 70 }; // The delay between steps for each PWM.

// To get a good effect select good initial values for the delay, value and increment.
// larger delays mean less frequent changes to the PWM duty cycle.
// larger increments means each adjustment to the PWM duty cycle is larger.
// Set the value at the starting point e.g. 0, for off, 127 for 50% brightness or 255 for 100%.

#define PINS sizeof(pwmValue)
unsigned long pwmNextStepTime[PINS]; // The point in time when the PWM will next be adjusted.

void setup() {
  for (int i = 0; i < PINS; i++) {   // Initialise each pin as:
    pinMode(pwmPin[i], OUTPUT);      // an output.
    pwmNextStepTime[i] = millis() + pwmDelay[i];   // The time when next the duty cycle shoud be adusted.
    analogWrite(pwmPin[i], pwmValue[i]);           // Set the duty cycle of the PWM.
  }
}

void loop() {
  // put your main code here, to run repeatedly:
  for (int i = 0; i < PINS; i++) {    // On each loop, check the PWM pin to see if we need to do anything.
    unsigned long now = millis();     // What is the current "time"?
    if (now > pwmNextStepTime[i]) {   // Has the time passed the adjustment time for PWM pin i?
      pwmNextStepTime[i] = now + pwmDelay[i];  // Yes, calculate the next adjustment time.
      pwmValue [i] += pwmIncrement[i];         // Adjust the duty cycle as per the pin's increment.
      if (pwmValue [i] >= 255) {               // Have we gone too far up?
        pwmValue[i] = 255;                     // Yes, set the maximum value.
        pwmIncrement[i] = -pwmIncrement[i];    // Reverse the increment (so now we count down)
      } else if (pwmValue[i] <= 0) {           // Have we gone too far down?
        pwmValue[i] = 0;                       // Yes, set the minimum value.
        pwmIncrement[i] = -pwmIncrement[i];    // Reverse the increment (so now we count up)
      }
      analogWrite(pwmPin[i], pwmValue[i]);     // Finally, set the duty cycle for the LED.
    }
  }
}

```

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


title: Handling arduino output current

text:
# Question
Title: Handling arduino output current
I need to power an actuator that requires 12 volts and consumes between 5 and 10 amperes depending on the weight it is charging. Therefore I bought a power supply of 12 volts and 10 amperes.

My intention is to send in the arduino output the 12 volts and the current provided by the power supply.

The options that I have thought are the following:

a) Connect the power supply to the arduino input pins and send the voltage and current from the power supply to the actuator through the arduino output (I know I could do it directly to the actuator, but I am interested in doing it through of arduino since it will involve programming code to put conditionals)

My doubt with this option is if I do not damage the arduino by connecting that power source with that amperage. If there is no problem, my question is if I could handle the current of the power supply at the output or the current could only be handled by what arduino gives that would not be much.

b) The other option that I think is simply to send a flag to the output and then this flag activates the power supply in some way and then I could use the 12 volts and the 10 amperes to connect them to the actuator.

I would like you to guide me on the alternatives I have thought about and tell me what would be the right thing to do, or if you know some other way in which you should do it.

Thank you very much in advance Cheers

# Answer
> 1 votes
As others have said, an Arduino pin can't handle 12V, and can't handle anywhere near 10A of current directly. A digital pin on an Arduino is limited to 20mA, or 1/500 as much current as you need, at 5V, which is less than half the voltage you need.

If you try to connect 12V to a pin on an Arduino pin you will almost certainly destroy that pin, and may destroy the entire Arduino. If you try to source or sink even 1/100 of the current you are talking about through an Arduino pin, even at 5V, you will also probably destroy that pin and possibly the entire Arduino.

This sounds like a good application for a power MOSFET transistor. With that much current you'll need to put a heatsink on the transistor.

Here's one that would work:

https://www.sparkfun.com/products/10213

You'd use a logic pin from the Arduino to control the gate on the transistor, and the transistor would switch 12V at high current with very little resistance.

If the actuator is inductive, you'll need to protect the transistor with a suitably large "flyback diode" to protect it from the reverse current (or "back EMF") you get from an inductor when you remove power from it:

https://en.wikipedia.org/wiki/Flyback\_diode

# Answer
> 0 votes
Duncan's answer is how I would do it as well. Indeed that is how I did do it as well.

Having said that the challenge I had to work out was how to mix the voltages. For me, this was the hardest part of the project as I had little idea about current and voltage.

I also wanted to use just one power supply.

So what's the problem? The LED strip requires 12V@1Amp. Which is, I think the upper limit for what can be supplied to arduinio's power jack. Also the arduino can only supply a small current at 5v to switch the relatively massive 12V 1A led circuit.

The MOSFET was the answer (after multiple failed attempts). MOSFETs are apparantly safe for connection to Arduino as there is apparantly no electrical connection between the base (where the arduino connnects) to the other two pins (where the power flows). The articles I read say that the base is insulated from the rest of the circuit by a piece of glass!

Anyway, Here is my Motion activated stair lighting project. I am not an electronics expert, but FWIW, this has been running flawlessly 24x7 for almost 12 months now.

---
Tags: power, motor, current, input, voltage
---


# Question
Title: Sending a string from Arduino to ESP8266 works on UNO but not on Pro Mini
I have a project where I am getting sensor data and sending it over to an ESP8266-01 to send to ThingSpeak. After some work I got it to work. So like a real smart person I decided to replace the Arduino UNO I was using (that worked) with an Arduino Pro Mini. Using the same code and connections the String isn't sent to the ESP and then not to ThingSpeak.

Here is a reduced version of the sending code that I used on the UNO and the Pro.

```
#include <FS.h>
#include <ESP8266WiFi.h> //https://github.com/esp8266/Arduino
#include <EEPROM.h>
//needed for library
#include <DNSServer.h>
#include <ESP8266WebServer.h>
#include <WiFiManager.h> //https://github.com/tzapu/WiFiManager
#include <ArduinoJson.h>
//#include <SoftwareSerial.h>

//SoftwareSerial espSerial(A0, D1); // RX | TX
//stuff to bring in string
const byte numChars = 32;
char receivedChars[numChars];
char tempChars[numChars]; // temporary array for use when parsing
// variables to hold the parsed data
char messageFromPC[numChars] = {0};
float floatFromPC = 0;
float floatFromPC2 = 0;
boolean newData = false;
//end stuff ti bring in string
String f;
String start = "start";
//NEW STUFF START
char Password[36] = "";
char apiKey[16] = "";
WiFiClient client;
//eeprom new end
char defaultHost[100] = "";
//Thing Speak IP address (sometime the web address causes issues with ESP :/
long itt = 500;
long itt2 = 500;
const byte wifiResetPin = 13;
int interruptPinDebounce = 0;
long debouncing_time = 1000;
volatile unsigned long wifiResetLastMillis = 0;
bool shouldSaveConfig = false;

void saveConfigCallback () {
  Serial.println("Should save config");
  shouldSaveConfig = true;
}

void handleWifiReset() {
  if (millis() < wifiResetLastMillis) {
    wifiResetLastMillis = millis();
  }
  if ((millis() - wifiResetLastMillis) >= debouncing_time) {
    Serial.println("Clearing WiFi data resetting");
    WiFiManager wifiManager;
    wifiManager.resetSettings();
    SPIFFS.format();
    ESP.reset();
    delay(1000);
  }
  wifiResetLastMillis = millis();
}
int addr = 0;
void setup() {
  //EEPROM.begin(512); //Initialize EEPROM
  WiFiManager wifiManager;
  Serial.begin(9600);
  //espSerial.begin(115200);
  pinMode(wifiResetPin, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(wifiResetPin), handleWifiReset, FALLING);
  WiFiManagerParameter customAPIKey("apiKey", "ThingSpeakWriteAPI", apiKey, 16);
  //END NEW STUFF
  //WiFiManager
  //Local initialization. Once its business is done, there is no need to keep it around
  //WiFiManager wifiManager;
  //NEW STUFF START
  //wifiManager.setSaveConfigCallback(saveConfigCallback);
  wifiManager.addParameter(&customAPIKey);
  //END NEW STUFF
  //reset saved settings
  //wifiManager.resetSettings();
  //set custom ip for portal
  //wifiManager.setAPStaticIPConfig(IPAddress(10,0,1,1), IPAddress(10,0,1,1), IPAddress(255,255,255,0));
  //fetches ssid and pass from eeprom and tries to connect
  //if it does not connect it starts an access point with the specified name
  //here  "AutoConnectAP"
  //and goes into a blocking loop awaiting configuration
  wifiManager.autoConnect("AutoConnectAP");
  Serial.println("Connected");
  //NEW STUFF START
  strcpy(apiKey, customAPIKey.getValue());
  if (shouldSaveConfig) {
    Serial.println("saving config");
    DynamicJsonBuffer jsonBuffer;
    JsonObject& json = jsonBuffer.createObject();
    json["defaultHost"] = defaultHost;
    json["apiKey"] = apiKey;
    Serial.println("API");
    Serial.print(apiKey);
    String apiKey2 = String(apiKey);
    File configFile = SPIFFS.open("/config.json", "w");
    if (!configFile) {
      Serial.println("failed to open config file for writing");
    }
    json.printTo(configFile);
    json.printTo(Serial);
    delay(1000);
    configFile.close();
    //end save
  }
  Serial.println("local ip");
  Serial.println(WiFi.localIP());
  //END NEW STUFF
  //or use this for auto generated name ESP + ChipID
  //wifiManager.autoConnect();
  //Serial.println("WriteApi");
  //Serial.println(apiKey);
  //if you get here you have connected to the WiFi
  //Serial.println("K)");
  //save the custom parameters to FS
  strcpy(apiKey, customAPIKey.getValue());
  EEPROM.begin(512); //Initialize EEPROM
  // write appropriate byte of the EEPROM.
  // these values will remain there when the board is
  // turned off.
  EEPROM.write(addr, 'A'); //Write character A
  addr++; //Increment address
  EEPROM.write(addr, 'B'); //Write character A
  addr++; //Increment address
  EEPROM.write(addr, 'C'); //Write character A
  //Write string to eeprom
  String www = apiKey;
  for (int i = 0; i < www.length(); i++) {
    //loop upto string lenght www.length() returns length of string
    EEPROM.write(0x0F + i, www[i]); //Write one by one with starting address of 0x0F
  }
  EEPROM.commit(); //Store data to EEPROM
  //Read string from eeprom
}

//callback notifying us of the need to save config
void loop() {
  //new stuff string
  recvWithStartEndMarkers();
  if (newData == true) {
    strcpy(tempChars, receivedChars);
    // this temporary copy is necessary to protect the original data
    //   because strtok() used in parseData() replaces the commas with \0
    parseData();
    showParsedData();
    newData = false;
  }
  //new stuff string end
  WiFiManager wifiManager;
  if (WiFi.status() == WL_DISCONNECTED) {
    wifiManager.autoConnect("AutoConnectAP");
  }
  delay(1000);
  if (WiFi.status() == WL_CONNECTED) {
    Serial.println("Connected");
    delay(1000);
    WiFiClient client;
    long itt = 50;
    long itt2 = 200;
    char defaultHost[100] = "api.thingspeak.com";
    EEPROM.begin(512);
    Serial.println(""); //Goto next line, as ESP sends some garbage when you reset it
    Serial.print(char(EEPROM.read(addr))); //Read from address 0x00
    addr++; //Increment address
    Serial.print(char(EEPROM.read(addr))); //Read from address 0x01
    addr++; //Increment address
    Serial.println(char(EEPROM.read(addr))); //Read from address 0x02
    //Read string from eeprom
    String www;
    //Here we dont know how many bytes to read it is better practice to use some terminating character
    //Lets do it manually www.circuits4you.com  total length is 20 characters
    for (int i = 0; i < 16; i++) {
      www = www + char(EEPROM.read(0x0F + i)); //Read one by one with starting address of 0x0F
    }
    Serial.print(www); //Print the text on serial monitor
    if (client.connect(defaultHost, 80)) { // "184.106.153.149" or api.thingspeak.com
      itt++; //Replace with a sensor reading or something useful
      String postStr = www;
      postStr += "&field1=";
      postStr += String(floatFromPC);
      postStr += "&field2=";
      postStr += String(floatFromPC2);
      postStr += "\r\n\r\n\r\n";
      client.print("POST /update HTTP/1.1\n");
      client.print("Host: api.thingspeak.com\n");
      client.print("Connection: close\n");
      client.print("X-THINGSPEAKAPIKEY: " + String (www) + "\n");
      client.print("Content-Type: application/x-www-form-urlencoded\n");
      client.print("Content-Length: ");
      client.print(postStr.length());
      client.print("\n\n\n");
      client.print(postStr);
      Serial.println("% send to Thingspeak");
    }
    client.stop();
    Serial.println("Waiting…");
  }
  delay(5000);
}

//more new stuff for string
void recvWithStartEndMarkers() {
  static boolean recvInProgress = false;
  static byte ndx = 0;
  char startMarker = '<';
  char endMarker = '>';
  char rc;
  while (Serial.available() > 0 && newData == false) {
    rc = Serial.read();
    if (recvInProgress == true) {
      if (rc != endMarker) {
        receivedChars[ndx] = rc;
        ndx++;
        if (ndx >= numChars) {
          ndx = numChars - 1;
        }
      } else {
        receivedChars[ndx] = '\0'; // terminate the string
        recvInProgress = false;
        ndx = 0;
        newData = true;
      }
    } else if (rc == startMarker) {
      recvInProgress = true;
    }
  }
}

void parseData() { // split the data into its parts
  char * strtokIndx; // this is used by strtok() as an index
  strtokIndx = strtok(tempChars, ","); // get the first part - the string
  strcpy(messageFromPC, strtokIndx); // copy it to messageFromPC
  strtokIndx = strtok(NULL, ","); // this continues where the previous call left off
  floatFromPC = atoi(strtokIndx); // convert this part to an integer
  strtokIndx = strtok(NULL, ",");
  floatFromPC2 = atoi(strtokIndx); // convert this part to a float
}

void showParsedData() {
  Serial.print("Message ");
  Serial.println(messageFromPC);
  Serial.print("Float ");
  Serial.println(floatFromPC);
  Serial.print("Float ");
  Serial.println(floatFromPC2);
}
//end new stuff string

```

Sorry for the length but... I don't know if I need to modify how I send the string or I have to turn on the TX and RX pins in the Pro Mini. I have tried connecting the RX Arduino to TX ESP and TX Arduino to RX ESP and RX to RX and TX to TX with no results. I know the pins work because I have programmed the ESP and the PRO numerous times with the TX and RX pins.

Can anyone help me with this? It is driving me crazy.

# Answer
> 0 votes
I finally got this to work by repeating the Serial.print (f); and then delay(1000); multiple times. I changed my original post to reflect this. Somehow this gets the string over to the ESP so it can parse it and upload it. Now all I want to do is add a temperature sensor and maybe add an IFTTT to the whole thing so if the low end gets too low or the high end too high (of the water level I can get a notification to check out the whole system. Thanks JRobert for the help I got the power I needed to the board.

---
Tags: arduino-uno, serial, esp8266, arduino-pro-mini, serial-data
---


# Question
Title: Arduino IDE doesn't pick up serial ports
I am fairly new to Arduinos and I recently bought a nodeMCU Amica esp2866 for this tutorial. I have my board connected to my MacBook Air (10.14.5 with Mojave) and only the "/dev/cu.Bluetooth-Incoming-Port" is the only one that shows up.

I am using a basic USB cord to connect the board to my MacBook and I know the cable isn't broken because I have used it in the recent past. If anyone knows how to fix this problem or has run into this problem in the past, please let me know. Let me know if you'd like anymore information. Thank you!

# Answer
The MAC / Arduino install instructions appear to be here.

If your Arduino (possibly a NodeMCU 1.0 version board) is using the CP210x chip set there appears to be a download page here.

If your Arduino (possibly a NodeMCU 0.9 version board) is using the ch340g, ch34g or ch34x chip set there appears to be an effort to create a Mac OS X driver here.

The install instructions from that github page are as follows:

> Installation
>
> ```
> Unplug any CH34* devices.
> Unload the old drivers if running:
>     sudo kextunload /Library/Extensions/usbserial.kext
>     sudo kextunload /System/Library/Extensions/usb.kext
> Remove the old driver by issuing one of the following commands (depending on your installation):
>     sudo rm -rf /System/Library/Extensions/usb.kext
>     sudo rm -rf /Library/Extensions/usbserial.kext
> Double-click on the CH34x_Install_V1.5.pkg file and install (no need to reboot)
> Instead of rebooting, you can force quit Installer after it completes.
> Load the new driver:
>     sudo kextload /Library/Extensions/usbserial.kext
> Plug in your device. It should now be listed under the /dev directory. Examples:
>     /dev/cu.wchusbserial1410
>     /dev/tty.wchusbserial14210 (driver version 1.5)
>
> ```
> 2 votes

---
Tags: arduino-ide, usb, nodemcu
---


# Question
Title: Error: exit status 1 stray '#' in program
I got this error:

```
exit status 1 stray '#' in program

```

How can I remove this error..?

```
int keys = {1,2,3,A,4,5,6,B,7,8,9,C,*,0,#,D};

```

# Answer
There are several -more or less severe- issues in your one line of code

```
const char keys[] = {'1','2','3','A'
                    ,'4','5','6','B'
                    ,'7','8','9','C'
                    ,'*','0','#','D' };

```

( Find the differences :) )

Depending on your usage, you eventually even need a 2-dimensional array

```
const char keys[4][4] =  ...

```
> 3 votes

---
Tags: programming
---


# Question
Title: Why won't this code play a converted wav2c header file through an Arduino to my speaker?
I used this converter wav2c to convert a .wav file to a C that I can put in a header file. I was able to put converted audio into the h file but the program where I reference it does not seem to be working correctly. The code compiles and uploads to the Arduino but no sound plays. I used the code here to implement the converted audio. I'm using an 8-ohm 0.25w speaker. I'm no programmer nor an expert at electronics so it's likely something dumb that I did wrong. Any help is much appreciated!

Note: The speaker does work with a simple tone sketch.

The code in the header file (minus the hundreds of lines of values for the audio)

```
#ifndef _HEADERFILE_H    // Put these two lines at the top of your file.
#define _HEADERFILE_H    // (Use a suitable name, usually based on the file name.)

const int sounddata_length=10000;
//const int sounddata_sampleRate=8000;

const unsigned char sounddata_data[] PROGMEM = {
  15,1,49,0,150,0,138,0,219,255,133,0,176,0,15,1,210,254,16,1,197,255,65,0,9,0,227,0,127,254,87,0,175,1,61,254,132,1,135,255,21,1,72,0,104,1,172,0,122,0,213,1,65,255,188,1,100,1,215,0,210,255,59,2,17,0,193,0,200,2,207,255,203,0,65,1,17,1,169,255,121,2,112,0,193,255,65,255,252,255,232,0,101,255,88,2,4,0,26,255,

//Several hundred lines more of these numbers for the audio

105,108,101,45,49,46,48,46,50,52,41,0,105,100,51,32,42,0,0,0,73,68,51,3,
  0,0,0,0,0,31,84,88,88,88,0,0,0,21,0,0,0,83,111,102,116,119,97,114,101,0,76,97,118,102,53,50,46,57,51,46,48,0,};

#endif // _HEADERFILE_H    // Put this line at the end of your file.

```

Here is the code that I used from the Arduino Playground page to play the audio from the header file.

```
#include <stdint.h>
#include <avr/interrupt.h>
#include <avr/io.h>
#include <avr/pgmspace.h>

#define SAMPLE_RATE 8000
#include "Test.h"

int ledPin = 3;
int speakerPin = 11; // Can be either 3 or 11, two PWM outputs connected to Timer 2
volatile uint16_t sample;
byte lastSample;

void stopPlayback()
{
    // Disable playback per-sample interrupt.
    TIMSK1 &= ~_BV(OCIE1A);

    // Disable the per-sample timer completely.
    TCCR1B &= ~_BV(CS10);

    // Disable the PWM timer.
    TCCR2B &= ~_BV(CS10);

    digitalWrite(speakerPin, LOW);
}

// This is called at 8000 Hz to load the next sample.
ISR(TIMER1_COMPA_vect) {
    if (sample >= sounddata_length) {
        if (sample == sounddata_length + lastSample) {
            stopPlayback();
        }
        else {
            if(speakerPin==11){
                // Ramp down to zero to reduce the click at the end of playback.
                OCR2A = sounddata_length + lastSample - sample;
            } else {
                OCR2B = sounddata_length + lastSample - sample;
            }
        }
    }
    else {
        if(speakerPin==11){
            OCR2A = pgm_read_byte(&sounddata_data[sample]);
        } else {
            OCR2B = pgm_read_byte(&sounddata_data[sample]);
        }
    }

    ++sample;
}

void startPlayback()
{
    pinMode(speakerPin, OUTPUT);

    // Set up Timer 2 to do pulse width modulation on the speaker
    // pin.

    // Use internal clock (datasheet p.160)
    ASSR &= ~(_BV(EXCLK) | _BV(AS2));

    // Set fast PWM mode  (p.157)
    TCCR2A |= _BV(WGM21) | _BV(WGM20);
    TCCR2B &= ~_BV(WGM22);

    if(speakerPin==11){
        // Do non-inverting PWM on pin OC2A (p.155)
        // On the Arduino this is pin 11.
        TCCR2A = (TCCR2A | _BV(COM2A1)) & ~_BV(COM2A0);
        TCCR2A &= ~(_BV(COM2B1) | _BV(COM2B0));
        // No prescaler (p.158)
        TCCR2B = (TCCR2B & ~(_BV(CS12) | _BV(CS11))) | _BV(CS10);

        // Set initial pulse width to the first sample.
        OCR2A = pgm_read_byte(&sounddata_data[0]);
    } else {
        // Do non-inverting PWM on pin OC2B (p.155)
        // On the Arduino this is pin 3.
        TCCR2A = (TCCR2A | _BV(COM2B1)) & ~_BV(COM2B0);
        TCCR2A &= ~(_BV(COM2A1) | _BV(COM2A0));
        // No prescaler (p.158)
        TCCR2B = (TCCR2B & ~(_BV(CS12) | _BV(CS11))) | _BV(CS10);

        // Set initial pulse width to the first sample.
        OCR2B = pgm_read_byte(&sounddata_data[0]);
    }

    // Set up Timer 1 to send a sample every interrupt.

    cli();

    // Set CTC mode (Clear Timer on Compare Match) (p.133)
    // Have to set OCR1A *after*, otherwise it gets reset to 0!
    TCCR1B = (TCCR1B & ~_BV(WGM13)) | _BV(WGM12);
    TCCR1A = TCCR1A & ~(_BV(WGM11) | _BV(WGM10));

    // No prescaler (p.134)
    TCCR1B = (TCCR1B & ~(_BV(CS12) | _BV(CS11))) | _BV(CS10);

    // Set the compare register (OCR1A).
    // OCR1A is a 16-bit register, so we have to do this with
    // interrupts disabled to be safe.
    OCR1A = F_CPU / SAMPLE_RATE;    // 16e6 / 8000 = 2000

    // Enable interrupt when TCNT1 == OCR1A (p.136)
    TIMSK1 |= _BV(OCIE1A);

    lastSample = pgm_read_byte(&sounddata_data[sounddata_length-1]);
    sample = 0;
    sei();
}

void setup()
{
    pinMode(ledPin, OUTPUT);
    digitalWrite(ledPin, HIGH);
    startPlayback();
}

void loop()
{
    while (true);
}

```

# Answer
> 1 votes
This program uses the Timer 2 PWM facility to generate audio output on pins OC2A or OC2B. On the Arduino Uno, these pins are labeled “11” and “3” respectively, and the program carries this mapping as an implicit assumption. You are trying to run the program on an Arduino Mega, which has a different pinout. For instance, on the Mega:

* OC2A = digital 10
* OC2B = digital 9

You can easily port the program to the Mega by replacing every reference to pins 11 and 3 by 10 and 9 respectively. E.g., every occurrence of

```
if(speakerPin==11){

```

becomes

```
if(speakerPin==10){

```

Make sure to fix the comments so that they remain consistent with the code.

And you should, of course, choose an appropriate pin for your speaker.

Side note: you are stressing the output pin if you connect it directly to an 8 Ω speaker. It's fine for a test as long as you don't care too much about the life span of your Arduino.

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


# Question
Title: What is the difference between Nano 328p-au and 328p-mu?
What is the difference between Nano 328p-au and 328p-mu? Does it have to do with the updated bootloader or is it just a different board design? I want to make sure I order the correct one and I could not find a proper answer so far. Thanks.

# Answer
The AU and MU on the chip just refer to the shape of the chip. AU is TQFP and MU is VQFN.

You can see the full list of suffixes here (select the red "Buy Now" tab for a table).
> 2 votes

---
Tags: arduino-nano
---


# Question
Title: Arduino UNO - Fluctuation of inputs and outputs
I have some pots (100K) on my Arduino board. When I raise the value of one those resistance other pots are being changed (Not too much but it's significant). I have no idea what's going on. I tried to use a capacitor at the beginning of the circuit but didn't work.

These fluctuations change the value of my sensors too. When I raise the value of something other quantities change.

I'm powering up my Arduino using a USB cable.

Any ideas?

# Answer
You seem to be experiencing cross-talk between the analog channels. This happens because all the channels are funneled by an analog multiplexer into the same sample-and-hold capacitor. If the source resistance is too high, then the capacitor does not have enough time to charge to the voltage of every channel.

Here is what the datasheet of the ATmega328P says about the issue:

> The ADC is optimized for analog signals with an output impedance of approximately 10 kΩ or less. \[...\] The user is recommended to only use low impedance sources with slowly varying signals, since this minimizes the required charge transfer to the S/H capacitor.

The problem can be mitigated by reducing the source impedance using a capacitor at every pot wiper, or by giving more time to the sample-and-hold circuit: make many dummy readings before the one reading you want to keep. The proper solution would of course be to replace the pots with 10 kΩ pots.
> 3 votes

---
Tags: arduino-uno, sensors, potentiometer
---


title: Understanding WiFi.printDiag(Serial)

text:
# Question
Title: Understanding WiFi.printDiag(Serial)
I am having difficulty with setting up websockets using the Arduino IDE with an ESP8266 ESP8266 Websockets problem and I have added WiFi.printDiag(Serial) to the main loop of my code. The Output I get (with my comments added) is

```
14:34:03.325 -> DIAGNOSTIC INFO   Debug Comment I added
14:34:03.325 ->
14:34:03.325 -> Mode: AP          Presume this means ESP is in AP mode
14:34:03.325 -> PHY mode:N        XXX
14:34:03.325 -> Channel: 1        Presume this means AP is on channel 1
14:34:03.325 -> AP id: 0          XXX
14:34:03.325 -> Status: 255       XXX
14:34:03.325 -> Auto connect: 1   XXX
14:34:03.325 -> SSID (0):         XXX
14:34:03.325 -> Passphrase (0):   XXX
14:34:03.325 -> BSSID set: 0      XXX

The AP is setup and I can see it in WiFI Analyser on my phone.
Is there a reference somewhere that explains the lines with XXX in them, or can
someone suggest meanings? Thanks

```

# Answer
> Mode: AP

In access point mode. Can also be STA or STA+AP for Station or dual role modes.

> PHY mode:N

Physical interface mode. At the moment it's in 802.11n mode. Depends on the AP you are connecting to if any.

> Channel: 1

Which WiFi channel you are communicating on

All the following are meaningless in AP mode. They only pertain to STA mode:

> AP id: 0

Internal ID of the access point you are connecting to, if any.

> Status: 255

Connection status

> Auto connect: 1

Automatically connect to an access point.

> SSID (0):

Name of the access point currently connected to.

> Passphrase (0):

Password used to connect to the current access point

> BSSID set: 0

BSSID (kind of like the MAC address) of the access point connected to.

As you can see, much of it is meaningless for access point mode, since it mostly is to do with connecting the ESP8266 to an existing network. In AP mode there's not a lot of debugging information you can get - "is it running?" is really all there is.
> 3 votes

---
Tags: esp8266, wifi
---


# Question
Title: Does LabVIEW Linx affect the communication speed with Arduino?
I am using LabVIEW to connect to Arduino Mega. I control a logic gate to switch the current On/Off and at the same time there is an I2C connection with a sensor. It came to my attention that the sensor time resolution is very low and I cannot get enough data points from the sensor (I know that the sensor is capable of much better resolutions). My question, is this a problem inherent to LabVIEW and Linx module or my program in LabVIEW? Should I turn to coding with Arduino programming language or C? note! My reason for using LabVIEW is that I need to sync timing of data aqcuisition with another device which is connected through another VISA port.

# Answer
> 0 votes
For specific timing requirements, my recommendation is to write your own Arduino code.

The Linx module deploys its own `ino` program to the Arduino and uses serial IO to send it commands and receive data from it. Open NI I/O Trace to observe that traffic.

---
Tags: i2c, datalogging, speed, labview
---


# Question
Title: Burning bootloader and uploading sketch on ATMEGA328
I have a ATMEGA328-PU (not a atmega328P-PU) and managed to install the boot loader on it using an Uno as ISP, but now i can not upload any sketch, this are the steps I've done so far:

connected this pins:

reset to pin10

11 to 11

12 to 12

13 to 13

and 5V to 5V and ground to ground.

uploaded ArduinoISP from examples and then changed the programmer to Arduino as ISP.

Then i changed this line in avrdude.conf:

```
part parent "m328"
    id          = "m328p";
    desc        = "ATmega328P";
    signature       = 0x1e 0x95 0x0F;

    ocdrev              = 1;
;

```

to:

```
part parent "m328"
    id          = "m328p";
    desc        = "ATmega328P";
    signature       = 0x1e 0x95 0x14;

    ocdrev              = 1;
;

```

selected burn bootloader and uploaded the boot loader with success.

and then i removed pin 10 to 13 and connected reset to reset, RX to RX and TX to TX and removed the chip from Arduino UNO.

added this lines to boards.txt:

```
##############################################################

uno328.name=Arduino328

uno328.vid.0=0x2341
uno328.pid.0=0x0043
uno328.vid.1=0x2341
uno328.pid.1=0x0001
uno328.vid.2=0x2A03
uno328.pid.2=0x0043
uno328.vid.3=0x2341
uno328.pid.3=0x0243

uno328.upload.tool=avrdude
uno328.upload.protocol=arduino
uno328.upload.maximum_size=32256
uno328.upload.maximum_data_size=2048
uno328.upload.speed=115200

uno328.bootloader.tool=avrdude
uno328.bootloader.low_fuses=0xFF
uno328.bootloader.high_fuses=0xDE
uno328.bootloader.extended_fuses=0xFD
uno328.bootloader.unlock_bits=0x3F
uno328.bootloader.lock_bits=0x0F
uno328.bootloader.file=optiboot/optiboot_atmega328.hex

uno328.build.mcu=atmega328
uno328.build.f_cpu=16000000L
uno328.build.board=AVR_UNO
uno328.build.core=arduino
uno328.build.variant=standard

```

Selected that from board menu changed the programmer to AVRISP mkll and tried to upload the blink sketch but it stuck on "uploading" and after a while says "an error occurred during upload".

*I triple checked the wiring!*

# Answer
> 2 votes
Use the https://github.com/MCUdude/MiniCore for ATmega328. It has Boards Manager installation. Choose the right options in Tools menu for your ATmega328.

First burn the bootloader using programmer or "Arduino as ISP". Then you can do serial upload as usual.

You can put the ATmega328 on Uno if you want.

---
Tags: atmega328
---