text:
A few Bitshifting questions!
So int in Arduino is 2 bytes, which could technically hold up to a value of 65535. However, the MSB is used as a sign bit, so now we have -32,768 to 32,767. So it's a signed integer, easy stuff. While I was messing around with bitshifting I ran across something interesting. If I do the following code:
int a = 1023 << 6;  // 1023 = 0b0000001111111111
Serial.println(a, BIN);

it returns a ridiculous number, 11111111111111111111111111000000, which is 4 bytes. I know this is some error with bit shifting into the signed bit, because if I do
int a = 1023 << 5;  // equals 111111111100000 as expected

It works just fine. Question 1: What is happening here? Where is that number coming from?
So I got smart (so I thought) and was like okay, if I need more bytes, then I'll just use long. So I tried the following code:
long a = 1023 << 6;
Serial.println(a, BIN);

I figured I'd have 3 "extra" bytes to shift my number into. However, the same number is returned. Question 2: What is happening?
Question 3: What is the order of operations with bitshifting?
Wire.write(CMD_VDR | PD_NPD | voltageLevel >> 6);

This code I wrote produces the correct result. However, what is the order of operations? Is it just left to right? Putting voltageLevel >> 6 in parenthesis does not change the output. It's working fine but I want to know why!
Thanks!

Your third part was tacked on after I'd started answering and it is largely unrelated to the rest of it. You can probably sort it out by looking at this.

research  sign extend

Please do not put multiple unrelated questions in one post.

timemage provided an excellent answer to your first question (upvoted!).
Let me try to answer the subsequent ones:

long a = 1023 << 6;

Here you are evaluating 1023 << 6, then assigning the result to a
long. It is important to realize that the C++ rules for evaluating an
expression do not depend on what you are going to do later with the
result. Given that 1023 is an int constant, the expression has the
type int and is evaluated as such. The result is then undefined
behavior, which just happens, because you are unlucky, to give
the expected value, i.e. −64.
Assigning −64 to a long converts the type while preserving the value.
This is sign extension at work. As explained by timemage,
println(long, int) casts the value to unsigned long, hence the
result you see.

What is the order of operations
[in the expression CMD_VDR | PD_NPD | voltageLevel >> 6]?

The shift has higher precedence than the bitwise OR. The expression is
thus equivalent to
CMD_VDR | PD_NPD | (voltageLevel >> 6)

C.f. C++ Operator Precedence.

Thank you for sharing the precedence list! That's quite helpful.

Well, technically I did attempt to answer the second one. It just wasn't as clear as how you'd put it. The storage I was talking about was the intermediate result of the right-hand side, which applies to both of their expressions. But, since you've written this I'm just going to vote yours up rather than try to clarify what I meant.

So int in Arduino is 2 bytes

This is not true in the general case, for what it's worth. It is true of the AVR based Arduinos though, which I'll assume are in use below.
Strictly speaking, when you do int a = 1023 << 6; with a 16-bit integer, all bets are off, because you're already in undefined behaviour. 1023 is type int right hand side is expected to be of type int and trying to store something that won't actually fit in a signed integer is undefined.
But for the moment, lets just say it does roughly what you expect with the bit pattern, like it would for an unsigned type. You've produced the bit representation for a signed 16-bit integer with the value -64.
You're calling the println(int, int) here.
It's in turn calling println(long, int) here. It is only handling signedness for base 10. So, you are just forwarding your -64 value to printNumber here, which handle unsigned long values (which may have been prefixed by - for base 10).
So you are converting a -64 into an unsigned long. Conversion to unsigned types reduce modulo their maximum value plus 1.  The 32-bit unsigned long maximum is 0xFFFFFFFF, with one added you get 0x100000000. In other words, you're ultimately printing 0x100000000 - 64, which is the number you're seeing.
1023 << 5 does not overflow the 16-bit signed int. Does not result in a negative number (again if we're being charitable about undefined behavior) and so you see different result.

"It is true of the AVR based Arduinos though," - (Not calling you out on this, but) for completeness it's worth mentioning that int is 2-bytes on an AVR Arduino with the gcc compiler because that is what the implementers of that compiler chose for it to do. Another C/C++ compiler on the same hardware might do things differently. Which is to say, the width of int is not a function of the hardware but of the compiler. The width of int is usually chosen as the native word size of that hardware, but on an AVR, that would be 8 bits which isn't nearly as useful as 16.

@JRobert Yeah, I didn't know how far into the weeds they wanted to go. It actually wouldn't be compliant to have a 8-bit int type an account of it not meeting the minimum required range, though gcc will let you do it with -mint8.  But yeah, a compliant compiler could target the AVR and do any number of things like that. E.g. you could make all of the integer types 64bit, even the char type and have CHAR_BIT be 64. Again, it's difficult to know where to stop with it.

I could put something like "The actual range of the int type is determined by the compiler rather than hardware. It is subject to the standards requirements to the extent that the compiler is trying to adhere a standard, which is partly under the control of what options have been specified to the compiler. The intention is normally to have it follow the standard and where possible to have it follow some notion of the natural integer size of the underlying architecture." or shorter "without going into the details it is ultimately the compiler that determines the int type size."

Thank you for the detailed response

@timemage: Fair enough! I do tend to see the details....


text:
Arduino Wire library and Type Cast help
I'm having troubles understanding this line of code that I see with every Arduino EEPROM tutorial.
int saveLocation = 4095;
Wire.write((int)(saveLocation >> 8));

Question 1: Do the parenthesis indicate that the bitshift happens BEFORE the type cast? What's the order of operations?
According to the wire library documentation, you can use wire to send the following:
Wire.write(value) // value to send as a single byte
Wire.write(String) // a string to send as a series of bytes
Wire.write(data, length) // an array of data to send as bytes, the number of bytes to transmit.

So my variable, int saveLocation = 4095 is not a string or array, so it must be a considered as a 'value', which means it's being sent as 1 byte.
Question 2: If it's being sent as 1 byte, why would I cast it to an integer of 2 bytes?
Question 3: If saveLocation is already an integer, why would cast it to int?
Question 4: Since int is two bytes, does wire.write only send out the lower byte?
Thanks in advance for the help.

you're missing 1/2 of the EEPROM addressing code

You are right about being confused. This casting doesn't make any sense.

Question 1: Do the parenthesis indicate that the bitshift happens BEFORE the type cast? What's the order of operations?

Yes, the bitshift happens before the casting because of the parentheses.

Question 2: If it's being sent as 1 byte, why would I cast it to an integer of 2 bytes?

You wouldn't. It is cast to uint8_t (aka byte) anyway by the parameter type.

Question 3: If saveLocation is already an integer, why would cast it to int?

Doesn't make sense to me either. You don't need to. Though it also doesn't hurt here (same goes for question 2)

Question 4: Since int is two bytes, does wire.write only send out the lower byte?

Yes, only the lower byte. The function parameter is of type uint8_t, which is exactly one byte. Thats the reason for the bit shifting. By shifting the value right by 8 you effectively shift the high byte to the low byte position.

Dude I thought I was nuts! But what I don't understand is if you search online for code to address EEPROM chips, they all use that line for sending data. I thought that surely I had to be missing something because EVERY tutorial has that same stupid line of code. Thank you for helping me clear this up!

Often when an example code is written it gets copied over and over throughout the internet.

Question 1: Do the parenthesis indicate that the bitshift happens BEFORE the type cast? What's the order of operations?

Yes. What's in the brackets is evaluated then the result cast to int.

Question 2: If it's being sent as 1 byte, why would I cast it to an integer of 2 bytes?

You wouldn't.

Question 3: If saveLocation is already an integer, why would cast it to int?

You wouldn't

Question 4: Since int is two bytes, does wire.write only send out the lower byte?

Yes, just the lowest 8 bits.
The cast to an integer is completely redundant here. It's not performing anything other than making the code harder to understand. You can remove it and it won't make any difference.
In fact the presence of the int cast triggers an overloaded function:
inline size_t write(int n) { return write((uint8_t)n); }

So it just re-casts it to an unsigned 8-bit integer (byte) anyway.

Thank you Majenko as well. I don't understand why all the code online for EEPROM chips use this line of code, it's beyond confusing.

source: Stack Exchange

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

sort: votes


text:
Notoriously unstable ESP8266 MQTT-client
I am doing a project where an ESP8266 receives data from an Arduino Uno and publishes it via MQTT. After a random amount of time, it will stop sending data to my MQTT broker. It might be an hour, it might be a day or two.
It's set up to send data every second, and I made a debug output telling me the WiFi signal quality as well. Seems like that's not it.
I have tried making checks that will reconnect to MQTT if it looses connection, and that it resets itself if it looses WiFi connection. I'm out of ideas right now, any help appreciated!
Here's my MQTT reconnnect function

void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    // Create a random client ID
    String clientId = "ESP8266Client-";
    clientId += String(random(0xffff), HEX);
    // Attempt to connect
    if (client.connect(clientId.c_str())) {
      Serial.println("connected");
      // Once connected, publish an announcement...
      client.publish("pressure/debug", "ESP8266: reconnected!");
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}

and here's where it checks for WiFi
void checkWifiConnection() {
  if (WiFi.status() != WL_CONNECTED)
  {
    int countdown = millis() + 15000;
    WiFi.mode(WIFI_STA);
    WiFi.begin(ssid, password);
    while (WiFi.status() != WL_CONNECTED) {
      if (countdown > millis()) {
      delay(500);
      Serial.println("Connecting to WiFi..");
      } else {
        Serial.println("Timed out! Restarting...");
        ESP.reset();
      }
  }
  }
}

Both are run every loop.
The arduino sends the data like it's supposed to, and I've lowered the connection speed to 19200bps in order to ensure a more stable connection, using SoftwareSerial. Any more things i could monitor? I tried it with two different ESP8266MOD/"ESP07" boards with the same result.
Here's a debug output:
09:13:05.039 -> unpub data 0/ AP:Akvasafe/ RSSI:-69 dB / Vcc:3519mV / free heap:49440 / fragmentation:1%

use esp8266 arduino core 2.4.2

Have you tried a more stable MQTT library? You haven't said which one you're using now.

@Juraj I'm using 2.5.0, is it not advisable?

@JaromandaX I'm using PubSubClient, it seemed to me like it was the most popular one out there.

2.5.0 has many problems

Popular doesn't mean stable :p but that one, when I used to use it, was fine

I use adafruit mqtt library. After a few fixes, it is running very stable.
Tips:
1) Make sure you put subscribe line BEFORE connecting to mqtt (you can put it in setup and connect to mqtt in loop)
Like:
Setup: mqtt.subscribe(&motor);
Loop: MQTT_connect();
Yes, you can both publish and subscribe at the same time.
2) IN THE LINE: Adafruit_MQTT_Client(server,port,user,pass)
CHANGE TO THIS: Adafruit_MQTT(server,port,clientid,user,pass)
Use this with client id (MUST BE UNIQUE (EG: Different for all clients))
or your client will be kicked off when other client with same id connects.
3) Convert value.lastread from char* to int : int val = atoi((char *)sensor.lastread);
More about ESP8266 & ESP32 : http://github.com/ajaybnl

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


text:
Slow speed with stepping motor
I am currently working on a project where I need a stepping motor and a servo running at the same time, the servo turns fine and the speed is ok, but the stepping motors speed is very slow and as a result it is loud. I tried the code for the stepping motor on its own and it runs faster, but when it is ran with the servo it is slow. I have follwed a few tutorials to get this to the stage it is at currently, I have removed any delays that i could find which did help a little, but it is still not enough.
The servo is powered from the arduino and the stepping motor is powered by a 12v plug. I am just not sure if there is something within this code that is causing it to slow down? Thank you for you time! The code that it is running slow from is here:

#include <Servo.h>

Servo myservo;

// Configurable Variables
int MaxServoTurn = 20;

// Spooky Variables
int pos = 0;
int customDelay;
int customDelayMapped;
const int pin_LED = 10;
const int pin_switch = 8;
const int stepPin = 3;
const int dirPin = 4;
boolean oldSwitchState = LOW;
boolean newSwitchState1 = LOW;
boolean newSwitchState2 = LOW;
boolean newSwitchState3 = LOW;
unsigned long timeNow = 0;
unsigned long timePrev = 0;
unsigned int timeWait = 100;
boolean flashingLEDisON = false;
boolean LEDstatus = LOW;
boolean keyPressed = false;
boolean buttonToggle = false;

// Setup only, call functions in here
void setup() {
  myservo.attach(9);
  //Sets the two pins as Outputs
  pinMode(stepPin, OUTPUT);
  pinMode(dirPin, OUTPUT);
  //Enables the motor to move in a particular direction
  digitalWrite(dirPin, HIGH);
  pinMode(pin_LED, OUTPUT);
  digitalWrite(pin_LED, LOW);
  pinMode(pin_switch, INPUT);
}

// This is the main controller for the application
void loop() {
  for (pos = 0; pos <= MaxServoTurn; pos += 1) {
    buttonLoop();
    if (buttonToggle == true) {
      myservo.write(pos);
      setupPotentiometer();
    }
  }
  for (pos = MaxServoTurn; pos >= 0; pos -= 1) {
    buttonLoop();
    if (buttonToggle == true) {
      myservo.write(pos);
      setupPotentiometer();
    }
  }
}

void buttonLoop() {
  newSwitchState1 = digitalRead(pin_switch);
  newSwitchState2 = digitalRead(pin_switch);

  newSwitchState3 = digitalRead(pin_switch);

  if (  (newSwitchState1 == newSwitchState2) && (newSwitchState1 == newSwitchState3) )
  {
    if ( newSwitchState1 != oldSwitchState )
    {
      if ( newSwitchState1 == HIGH ) {
        keyPressed = true;
        buttonToggle = true;
      } else {
        keyPressed =  false;
        buttonToggle = false;
      }
      oldSwitchState = newSwitchState1;
    }
  }

  if ( keyPressed )
  {
    // turn on or turn off the blinking LED
    if ( flashingLEDisON == false)
    {
      flashingLEDisON = true;
    }
    else
    {
      flashingLEDisON = false;
      // the LED may be on so to be safe we turn it off. If you wished you could check LEDstatus
      LEDstatus = LOW;  digitalWrite(pin_LED, LEDstatus);
    }
    keyPressed = false;
  }

  // if the blinking LED is on. See if it is time to blink it
  if ( flashingLEDisON == true )
  {
    timeNow = millis();
    if (timeNow - timePrev >= timeWait )
    {
      timePrev = timeNow;
      if (LEDstatus == LOW) {
        LEDstatus = HIGH;
      } else {
        LEDstatus = LOW;
      }
      digitalWrite(pin_LED, LEDstatus);
    }
  }
}

void setupPotentiometer() {
  customDelayMapped = speedUp(); // Gets custom delay values from the custom speedUp function
  // Makes pules with custom delay, depending on the Potentiometer, from which the speed of the motor depends
  digitalWrite(stepPin, HIGH);
  delayMicroseconds(customDelayMapped);
  digitalWrite(stepPin, LOW);
  delayMicroseconds(customDelayMapped);
}

// Function for reading the Potentiometer
int speedUp() {
  int customDelay = analogRead(A0); // Reads the potentiometer
  int newCustom = map(customDelay, 0, 1023, 300, 4000); // Convrests the read values of the potentiometer from 0 to 1023 into desireded delay values (300 to 4000)
  return newCustom;
}

I had a project where I needed to run two steppers at the same time as they were moving a heavy load and were moving the same piece.
While a servo is going to move the desired spot, a stepper will not.
In the process of setting up the stepper you designated steps per rev and amount of steps to take at a time.
The stepper is only going to move the "amount of steps" at a time for each run of the code. I ran into a similar  problem and I had to put in a 2ms delay after the servo run command to make the motors run smoother and faster, other wise it sounded like a bunch of gears gnashing and skipping.  These steppers were facing each other that is why they move opposite directions.

if (down==true){
  TLstep.step(-step1);
  TRstep.step(step1);
  delay(2);
}

I know it been a year since this was looked at. Hope you got your issue figured out.

A stepper motor requires that you send pulsed control signals to it for each step. If you want it to run at a given number of steps/second, you have to send the controlling pulses at the correct time intervals.
If you have delays in your code, it will slow down the timing of the control pulses, and slow down your steppers. You need to rewrite your code to use millis() to calculate the timing of your control signals instead of using delay() or delayMicroseconds()

Thank you for your reply Duncan, do I just change the two delayMicroseconds(customDelayMapped); to millis() as you mentioned? I’m pretty new to the arduino so I’m sorry if I’m misunderstanding this!

no, you need to refactor your code to keep track of elapsed time and change states when the desired time interval has passed. Do a search on "Arduino Blink Without Delay" and study the sketches you find. It won't be a copy/paste change but rather a refactoring of your code. You might be able to find sample code for steppers and servos that doesn't use delays, which would make your job easier.


text:
Why can't I switch off the LED immediately using this sketch?
I hope the LED can fade out a period of time. Also, I hope I can switch off the LED immediately when it is fading, but I only can fade out.
const int buttonPin = 2;
const int ledPin = 9;
const int fadingDelay = 20000;
int buttonState = 0;
boolean fadingState = false;
void setup() {

// initialize the LED pin as an output:
  pinMode(ledPin, OUTPUT);
  // initialize the pushbutton pin as an input:
  pinMode(buttonPin, INPUT);
}
void loop() {
  // read the state of the pushbutton value:
  buttonState = digitalRead(buttonPin);

  // check whether the button was pressed
  if (buttonState == HIGH) {
    buttonState = LOW;
    // check the current LED status (on/off)
    if (fadingState == false) {
      // turn on the LED
        for (int i = 255; i >= 0; i -= 5) {
          if (buttonState == HIGH && fadingState == true) {
          analogWrite(ledPin, 0); //immediately off
          i=-1;
          }
        analogWrite(ledPin, i);
             delay(fadingDelay);

    }
    fadingState = false;  // save the current LED state (on/off)
  }
}
}

see the BlinkWithouDelay example. now your sketch stops for 20 seconds.

Your code is a mess, and won't work properly. You need to clearly define what you want to do before we can help you.

I can't see anywhere where you are assigning fadingState as true.I can't understand this part
if (fadingState == false) {
      // turn on the LED
        for (int i = 255; i >= 0; i -= 5) {
          if (buttonState == HIGH && fadingState == true) {
          analogWrite(ledPin, 0); //immediately off
          i=-1;
          }
    analogWrite(ledPin, i);
    delay(fadingDelay);
    }

If you are entering in a if condition with statement fadingState as false. Then in for loop you are having a if condition in which statement is fadingState == true.If you are entering in as a False then why are you looking for True Condition.
Then if you manage to sort that add break; in that if condition so that when LED turns OFF you will exit that for Loop.
And Here you are setting the button state as low buttonState = LOW if first If condition, then in that nested if without reading the buttonState you still looking for it as HIGH.


text:
Arduino stops working when servo makes a few rotations
The sketch rotates servo back and forth with buttons.
When I rotate servo MG 995/996R 2-4 times Arduino stops working. Its voltage step-down transformer switches from ~9V to ~3.7V which is not enough for Arduino. To make it work again, I must turn off-on the device.
There is no such a glitch with smaller servos such as SG90.

Show us your sketch. Throwing an exception in the code has very similar symptoms. I also don't like that your servo ground is connected to the Arduino. It's much safer for it to be completely disconnected and using an optoisolator to send the PWM to it safely. Are you certain that your 12V power supply keeps at 12V when the problem happens?

" a few rotations" sounds strange, as such a servo can't rotate much more than 180°
And I do not see nor understand your term "3.7 V". Please clarify.

@FilipFranik There is no any exception. As I said, everything perfectly works with smaller servo. Therefore the problem not in the sketch.

@DataFiddler I haven't said any about the angle. The bottom transformer set to 9V. After rotations it becomes set to ~3.7V which is not enough to power-up the arduino via VIN pin. And btw, your're wrong about angles. There are servors with greater that 180 rotation.

So the problem is the transformer, because it outputs a too low voltage

@chrisl , I'm afraid it is not. The question is what produces such current to send the transformer to protection mode.

Test for eventual clarification: What if you don't connect the servo control line (orange) to Arduino D9 ? What if you don't use the two different GND connections (already mentioned)

Ground loops can be bad.  Do follow up as suggested in the comments regarding ensuring the power supply grounds are the same. To be specific, connecting the power supply grounds through the Arduino is a bad idea! The trace size should not be assumed adequate for the unknown amount of current passing between the ground outputs of the power supplies.  And a voltage potential can develop causing the processor to behave unexpectedly or worse burn out components.
Also, consider that some Arduino platforms regulate power to 5 volts on the board and that many servos run fine at 5 volts. If this is true here, you could greatly simplify and possibly solve the describe problem by using a single 5 volt power supply.
Lastly, ensure there is a pull up on the 2 inputs connected to the (assumed) normally-open-momentary-contact switches.  There are none in the diagram.  So it is assumed pull ups have been activated in the code such as explained here.


text:
Protect the Arduino make with Unique Id
I’d like to protect my arduino make with a unique serial number for every device I make.
What are the proper ways to do it? Probably there are kind of best practices…
Keep it in EEPROM is obviously a bad idea.
I believe that there is some chip that can be added to the circuitry.
The general idea is the following.
Circuitry has a hardware which gives a unique id (serial number). Distributor/seller generates the signature using unique id and put it to the eeprom. Arduino program verifies this signature using hardware serial number. Arduino program is distributed in binary or within the device.

Why is EEPROM a bad idea for this?

Because it can be rewritten easily.

And even with an extra chip, the sketch on the Arduino needs to send read and send the ID of the device. One could easily change the sketch to not send the ID from the extra chip, but a custom one. Unless you connect the extra chip directly to the external device or you use encryption, it is still possible to change. What are you trying here? Is it a safety measure, so that no one temperes with your device? Or do you just want to prevent to accidentially override it?

@chrisl, I distribute hex only, no sources. Since that nobody can alter the sketch. I am trying to protect my hex from easy copying.

"Since that nobody can alter the sketch." This is plain wrong. It is no problem to decompile hex dumps of several KB, especially if you know the hardware. I've done that multiple times.

@thebusybee, so, what do you suggest?

It depends on why and against what you want protection.

@thebusybee If you can read assembler code, you are elite, I believe. But simple farmer can’t. Disassembling requires special intelligence.  However, a humble farmer is able to install Arduino IDE and follow some simple instructions. But he won’t ever disassemble the hex, alter it and compile it again.

@thebusybee I want to have a reasonable protection of my makes from copying without purchasing.

Then your external chip has to contain a cypher algorithm that will be feeded by an identifier from your sketch. That chip has to be serialized so that different chips will return different results on the same identifier. The chip must have protection against reading it. -- Only the correct identifier will produce some values that are urgently needed to run the sketch. This could be some machine code parts of a kernal. Without this values it wont run.

But beware! Don't just return a boolean saying "OK/Error". It far too simple to patch that single instruction to disable the protection scheme. Such a patch will spread much faster than you can call "Stop!" -- And you have to think about what to do if some curious guy reveals the secret contents and publishes it. This already happened, I watched it, and will happen again.

Let us continue this discussion in chat.

I still suggest using the eeprom.
It is the firmware's job to handle whether or not data in eeprom can be written.
You could implement wrapper functions for the arduino which can only read/write after a defined offset. You can set this read-only data with the .eep-file when you upload your sketch. The eeprom file then may be generated programmatically.
Once you have to flash several individual devices with a final firmware version, there are no benefits in using the arduino ide. You can upload the firmware and the eeprom file using avrdude:
avrdude -P YOUR_PORT -b 115200 -p ATmega328P -e -U flash:w:YOUR_FIRMWARE.hex -U eeprom:w:YOUR_EEPROM.eep

It's up to you how to generate the eeprom file (bash/batch, make, pyhton,...).

Sounds interesting! Can you add an example how to use it?

I don't get it. Anybody can upload eeprom file from another arduino. I want to protect my devices from copying.

@zhekaus doesn't the upload work? You have to run the command from the build directory. You may have to select a programmer, but I think avrdude would force you. The simplest to get an eeprom file to start with might be to initialize the eeprom with temporary firmware which stores the desired values and then read-back the .eep-file using the above command with eeprom:r:initial.eep.

@zhekaus also, what do you mean by "protect my devices from copying"? An attacker would be able to read or write any unencrypted data the same way you do anyway.

nobody asks how to upload eeprom. Let's stick to the initial question, please ))

attacker does not know how to verify this unencrypted data. Official distributor does. PS. How to @ your nickname, Sim Son?

@zhekaus select an respond to comment for the '@' or type it manually (no spaces)

Sim Sin, of course, I know it. But stackexchange does not allow this with your two-word nickname ))

My general idea is: Circuitry has a hardware which gives unique id (serial number). Distributor/seller generates the signature using unique id. Arduino program verifies this signature using hardware serial number. Signature is stored in eeprom. Arduino program is distributed like binary.

Hmm, I can't read that in your question, but now I got it due to the comments. "Hidden in data" is not the same as "encrypted" and therefore storing such information at dedicated addresses in flash means no security. You can encrypt the information beforehand, but if it's encrypted you can use the eeprom.

I don’t understand your proposal. Anybody can copy hex and eeprom from one Arduino to another. Where is the protection here? It does not mattet whether it's encrypted or not.
However, nobody can copy DS2401.

Anyone who hooks up some wires can read the ds2401.

Maybe he can read. But can he forge? Allrighty, anyway, when we talk about the protection, we always keep in mind the cost of breaching it. Certainly, nobody believes in absolutely robust security. The question is in the cost of breeching. Yeah, probably DS2401 is not a good idea, but at least, it already looks like much better than simple keeping unique id in eeprom, since anybody can copy it with avrdude.

Then hacker will do it the same way old DOS games was cracked - dowload and debug the hex - overwrite the function reading DS2401 to not read it and return correct value insted, then distribute the modified hex. Anybody can download it, burn it and whether they have or not the DS2401, the function will return correct result and the Arduino will work the same way, the original one worked. Needs one "elite hacker" and internet copy to work on as many Arduinos as its users wants. That said, I do not think that this approach is working nor the best possible one.

I found a way! I can use DS2401 or DS2411.
These devices are 64-bit read only memory (ROM) "silicon serial number" devices which are programmed by the manufacturer with a unique 48 bit serial number, an 8 bit product family code, and an 8 bit CRC.

it can be removed, replaced

If it's removed, device won't work. Also, I suppose to keep a signature in eeprom which will be verified with unique id. If it’s not verified, device won’t work.

@zhekaus (See my comment at your question,too.) Since your sketch can be decompiled it is no problem to work around any protection you implemented.

@thebusybee You are right. But it requires extra skills, much more advances than avrdude using. My makes are not rocket science. I simply want to have a reasonable protection, nothing fancy or extremely robust.


text:
Reading DHT22 reboots arduino
I’ve got a quite weird behavior of DHT library.
I’ve got DHT22 sensor. If it’s signal cable is not connected, reading the sensor causes a problem: Arduino reboots or hangs in unpredictable places.
If I connect the signal cable again, the problem vanishes.
Is this normal behavior or some sort of bug? I think unsuccessful reading affects some part of Memory.
PS. The project is quite big and I can’t share the code here.
It happens that I found an evidence that dht object influences foreign memory. Look at this code:
DV("pClock->isInited 3", pClock->isInited); // prints 1
dht1.readHumidity();
DV("pClock->isInited 4", pClock->isInited); // print 0 !!!!
// nothing more can be called between these lines.

// DV is a macro which prints label and value.
// Both objects created before this.

DHT dht1(11, DHT22);
…
dht1.begin();
…
pClock = new ZhClock(); // uses RTC_DS1307
pClock->init(&rtc); // rtc is RTC_DS1307

It's not normal behaviour. What hardware are you using, what pins have you connected the DHT22 to, and what DHT library are you using?

@StarCat I use Arduino nano CH340. DHT library shipped with Arduino IDE. I tried pins D11 and A2.

Is that the DHT library from Adafruit (installed through the library manager)? I don't think there is a DHT library that comes standard with the Arduino IDE. A2 and D11 should work fine. But what do you expect it to do when you disconnect the signal cable? The library should return an error (NaN values returned by temperature and humidity) when the DHT is not connected. How do you handle these errors? If you continue using the NaN values returned by the library, you will mess up all subsequent calculations. Also remember you cannot read from a DHT22 more than once every 2 seconds.

@StarCat Why I cannot read more than once? Can this be the source of the problem? I was supposed that I get wrong results, but it cannot lead the memory leakage. Yes, this library is by Adafruit, I was wrong.

I meant that your code has to wait at least 2 seconds after reading it, before reading the DHT again (technically: 0.5Hz or less).

@StarCat , So, this is not the case. Please look an updated description, please.

Whatever you say, now I know that Adafruit DHT library is the worst library ever I met! It is occurred that simple reading call wastes a huge amount of memory! About 280 bytes or so. Shame, shame, shame!

@zhekaus Are you talking about RAM or the program memory? What do you mean by wasting memory? When you don't use the library, the compiler will optimize it out. When you then change your sketch to actually use it, the compiler will put the library (or only the needed parts of it) in, which results in a bigger sketch and partly in a bigger RAM usage.

@chrisl , I am talking about RAM, obviously. Shortage of RAM kills the device. Look into dht.cpp, DHT::read method, and you'll see it yourself.  I am sure, that, for instance , uint32_t cycles[80]; says quite something to you ;-).

Adafruit DHT library requires about 390 byte of free RAM. Check if you have so.

This problem is usual if you are in shortage of RAM.
Adafruit's libraries wastes lots of memory. You should be very careful to run their stuff if you are in shortage of memory.
I suggest you to try another library which quite old, but uses much lesser memory to read DHT sensor’s data:
https://github.com/markruys/arduino-DHT

Yep! That's solved my problem!


text:
External vs internal pullup
There are two ways of pulling the pins in Arduino – using internal and external resistor. I wonder when I should use external resistor instead of INPUT_PULLUP.

From my experience the only difference is "external pullup/pulldown is easier to replace" and maybe also "by just looking at the circuit you can see the external resistor so it's easier to understand the design after few months"

You can use either the internal or external resistor in normal application.
Each method has each own advantages:
Internal resistor

Pros: flexible to change by changing the code
Pros: Reduce PCB size
Pros: Reduce cost (very small)
Cons: It may make MCU hot

External resistor

Pros: Reduce heat for MCU
Cons: Not easy to replace when it is built-in PCB
Cons: Increase PCB size

Besides, Pull-up and pull-down resistors are not only used for INPUT port but also for OUTPUT port. In the case of OUTPUT port. The external resistor has another advantage:  flexibility in connecting devices with different I/O voltages. For example, in I2C hardware see I2C at the Hardware Level.
NOTE: As far as I know, at the writing time, Arduino library does NOT support INPUT_PULLDOWN

The heat generated by the internal pullup is negligible. 2. Some boards (not the AVR-based ones) have INPUT_PULLDOWN.

"Cons: It may make MCU hot"
It will not. P=V^2/R, so 5*5/20,000 = 1.25mW, that will not make the processor hot. Even turning all 80 in a Mega2560, and pulling them all low, will only dissipate 0.1W.
"NOTE: As far as I know, at the writing time, Arduino library does NOT support INPUT_PULLDOWN"
That is because Atmega328P, '1284, '2560, etc. family of devices do not have internal pulldown resistors. Only pullup. See Section 14 of their datasheets, "I/O Ports".
This pullup is generally insufficient for I2C pullup, the rising edge created by the 20K to 50K internal pullup is very slow. External 4.7K down to around 2.2K (depends on how many I2C devices are connected) are needed. And the I2C bus spec says they should be at the end of the bus, not the origin of bus (which is generally the processor).
If you have a long wire coming from a button or switch, that is generally a good time to use an external pullup to ensure good switching levels between high and low.

The "Arduino Language" (i.e. the pinMode() function) only knows INPUT_PULLUP.
So you need external resistors for PULLDOWN resistors.
OUTPUT signals are not floating, so the term PULLUP/PULLDOWN resistor does not really apply there.
Besides, the value of an internal pullup resistor is not adjustable. If that value (20 .. 50k) is not appropriate (I²C needs something less than 10k) an external resistor is required.

As I wrote in a comment to the previous answer, some Arduino cores do support INPUT_PULLDOWN.


text:
Simultaneous Serial reading and writing
I am trying to read long strings from the Serial, using arduino.
In order to spare some RAM I don’t use Serial.readString().
I use Serial.read() instead.
During the reading, I also print some debug info to the same Serial port.
Let's say I send 90 characters to the Serial from the PC. I read them with Serial.read(). If I call a few times Serial.println() between two calls of Serial.read(), I get only 67 character of 90 (Serial.available()>0 is false).
I read all the 90 character when I don’t call Serial.println() at all.
Why? I was sure that it is possible to write to the serial and read from it simultaneously, that these are independent processes.
Am I wrong?

I don't understand, what you mean by "as much I print ... as shorter read string is". Please explain more and more clear

Please show us the sketch you're using.

I send 90 characters to the serial. I read them with Serial.read(). If between to calls of Serial.read() I call Serial.println() a few times, I read only 67 character of 90. I read all the 90 character when I don’t call Serial.println at all.

@VE7JRO ,I believe I described my issue well enough. The sketch is quite long and it will take some time to cut it out.

what command uses this comparison? ... Serial.available()>0

@jsotola you can read about this on arduino.cc

The Serial buffer size is only 64 bytes. If you take too long for printing and your PC sends the data too fast, you will loose data. But that depends on your sketch, how much data you are printing and what baudrate you use

You can indeed simultaneously read and write through the serial port. At
the hardware level, the serial port (the UART) is a transmitter and a
receiver, which are almost independent. At the software level, they are
both handled through interrupts that read from / write to a software
buffer.
There is, however, a limitation you should be aware of: the software
buffers are not large, typically 64 bytes on AVR-based boards. If
you try to write too much too often, the output buffer will fill out,
and then all subsequent writes become blocking, and run as slow as the
serial port itself. If you receive lots of data and do not read it soon
enough, the input buffer will overflow, and you loose some data.
From your description of your issue, it would seem you are hitting the
limits of both buffers. You Serial.println() too much, too often. Then
these write operations take too long and, in the meanwhile, you do not
Serial.read(). Since your PC is not waiting for you to
Serial.read(), your input buffer eventually overflows, and you only
get slightly more than a buffer worth of characters.

I'm completely satisfied with your answer. Thank you so much indeed!


text:
Problem with reading data from HMC5883L in GY-86
I am trying to read the data from GY-86 with my arduino UNO.
While reading MPU6050 and MS5611, it works quite well. But somehow I can't read anything from HMC5883L. Here is the code I used:
#include <Wire.h>
#include <HMC5883L.h>

HMC5883L compass;

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

  // Initialize HMC5883L
  Serial.println("Initialize HMC5883L");
  while (!compass.begin())
  {
    Serial.println("Could not find a valid HMC5883L sensor, check wiring!");
    delay(500);
  }

  // Set measurement range
  // +/- 0.88 Ga: HMC5883L_RANGE_0_88GA
  // +/- 1.30 Ga: HMC5883L_RANGE_1_3GA (default)
  // +/- 1.90 Ga: HMC5883L_RANGE_1_9GA
  // +/- 2.50 Ga: HMC5883L_RANGE_2_5GA
  // +/- 4.00 Ga: HMC5883L_RANGE_4GA
  // +/- 4.70 Ga: HMC5883L_RANGE_4_7GA
  // +/- 5.60 Ga: HMC5883L_RANGE_5_6GA
  // +/- 8.10 Ga: HMC5883L_RANGE_8_1GA
  compass.setRange(HMC5883L_RANGE_1_3GA);

  // Set measurement mode
  // Idle mode:              HMC5883L_IDLE
  // Single-Measurement:     HMC5883L_SINGLE
  // Continuous-Measurement: HMC5883L_CONTINOUS (default)
  compass.setMeasurementMode(HMC5883L_CONTINOUS);

  // Set data rate
  //  0.75Hz: HMC5883L_DATARATE_0_75HZ
  //  1.50Hz: HMC5883L_DATARATE_1_5HZ
  //  3.00Hz: HMC5883L_DATARATE_3HZ
  //  7.50Hz: HMC5883L_DATARATE_7_50HZ
  // 15.00Hz: HMC5883L_DATARATE_15HZ (default)
  // 30.00Hz: HMC5883L_DATARATE_30HZ
  // 75.00Hz: HMC5883L_DATARATE_75HZ
  compass.setDataRate(HMC5883L_DATARATE_15HZ);

  // Set number of samples averaged
  // 1 sample:  HMC5883L_SAMPLES_1 (default)
  // 2 samples: HMC5883L_SAMPLES_2
  // 4 samples: HMC5883L_SAMPLES_4
  // 8 samples: HMC5883L_SAMPLES_8
  compass.setSamples(HMC5883L_SAMPLES_1);

  // Check settings
  checkSettings();
}

void checkSettings()
{
  Serial.print("Selected range: ");

  switch (compass.getRange())
  {
    case HMC5883L_RANGE_0_88GA: Serial.println("0.88 Ga"); break;
    case HMC5883L_RANGE_1_3GA:  Serial.println("1.3 Ga"); break;
    case HMC5883L_RANGE_1_9GA:  Serial.println("1.9 Ga"); break;
    case HMC5883L_RANGE_2_5GA:  Serial.println("2.5 Ga"); break;
    case HMC5883L_RANGE_4GA:    Serial.println("4 Ga"); break;
    case HMC5883L_RANGE_4_7GA:  Serial.println("4.7 Ga"); break;
    case HMC5883L_RANGE_5_6GA:  Serial.println("5.6 Ga"); break;
    case HMC5883L_RANGE_8_1GA:  Serial.println("8.1 Ga"); break;
    default: Serial.println("Bad range!");
  }

  Serial.print("Selected Measurement Mode: ");
  switch (compass.getMeasurementMode())
  {
    case HMC5883L_IDLE: Serial.println("Idle mode"); break;
    case HMC5883L_SINGLE:  Serial.println("Single-Measurement"); break;
    case HMC5883L_CONTINOUS:  Serial.println("Continuous-Measurement"); break;
    default: Serial.println("Bad mode!");
  }

  Serial.print("Selected Data Rate: ");
  switch (compass.getDataRate())
  {
    case HMC5883L_DATARATE_0_75_HZ: Serial.println("0.75 Hz"); break;
    case HMC5883L_DATARATE_1_5HZ:  Serial.println("1.5 Hz"); break;
    case HMC5883L_DATARATE_3HZ:  Serial.println("3 Hz"); break;
    case HMC5883L_DATARATE_7_5HZ: Serial.println("7.5 Hz"); break;
    case HMC5883L_DATARATE_15HZ:  Serial.println("15 Hz"); break;
    case HMC5883L_DATARATE_30HZ: Serial.println("30 Hz"); break;
    case HMC5883L_DATARATE_75HZ:  Serial.println("75 Hz"); break;
    default: Serial.println("Bad data rate!");
  }

  Serial.print("Selected number of samples: ");
  switch (compass.getSamples())
  {
    case HMC5883L_SAMPLES_1: Serial.println("1"); break;
    case HMC5883L_SAMPLES_2: Serial.println("2"); break;
    case HMC5883L_SAMPLES_4: Serial.println("4"); break;
    case HMC5883L_SAMPLES_8: Serial.println("8"); break;
    default: Serial.println("Bad number of samples!");
  }

}

void loop()
{
  Vector raw = compass.readRaw();
  Vector norm = compass.readNormalize();

  Serial.print(" Xraw = ");
  Serial.print(raw.XAxis);
  Serial.print(" Yraw = ");
  Serial.print(raw.YAxis);
  Serial.print(" Zraw = ");
  Serial.print(raw.ZAxis);
  Serial.print(" Xnorm = ");
  Serial.print(norm.XAxis);
  Serial.print(" Ynorm = ");
  Serial.print(norm.YAxis);
  Serial.print(" ZNorm = ");
  Serial.print(norm.ZAxis);
  Serial.println();

  delay(100);
}

I download it from https://github.com/jarzebski/Arduino-HMC5883L.
The program always stuck at
  while (!compass.begin())
  {
    Serial.println("Could not find a valid HMC5883L sensor, check wiring!");
    delay(500);
  }

Here is the begin function in HMC5883L.cpp
bool HMC5883L::begin()
{
    Wire.begin();

    if ((fastRegister8(HMC5883L_REG_IDENT_A) != 0x48)
    || (fastRegister8(HMC5883L_REG_IDENT_B) != 0x34)
    || (fastRegister8(HMC5883L_REG_IDENT_C) != 0x33))
    {
    return false;
    }

    setRange(HMC5883L_RANGE_1_3GA);
    setMeasurementMode(HMC5883L_CONTINOUS);
    setDataRate(HMC5883L_DATARATE_15HZ);
    setSamples(HMC5883L_SAMPLES_1);

    mgPerDigit = 0.92f;

    return true;
}

So, it seems that the begin function always returns False. What should i do to solve this problem?
This is how I connect GY-86 to UNO:
VCC-IN  -> 5V
GND     -> GND
SDA     -> 4A
SLC     -> 5A

Did you run a i2c scanner? Is it found with i2c address 0x1E?
Looking at the schematic, the magnetometer HMC5883L is connected to XDA and XCL. That is not the normal I2C bus, but a second I2C bus from the MPU-6050.
The reason for that is that the 'dmp' firmware in the MPU-6050 can read the magnetometer and do calculations with it, in the MPU-6050.
If you want to communicate with the magnetormeter via the normal I2C bus, then you have to turn on the bypass-mode.
The libraries from Jeff Rowberg and Jarzębski are large. I suggest to enable the bypass-mode and run a i2c scanner.
Do you have a logic analyzer?
Perhaps you can use a simple multimeter. Keep the SDA low (shortcut it to GND) and try to measure if XDA is low as well in the bypass mode.
There is a chance that something is broken.

It might be a problem here.  A i2c scanner only found 0x68 and 0x77. Does it means that my GY-86 is broken?

By the way, I also try to use the I2Cbypass code in this website
link
`mpu.setI2CMasterModeEnabled(false);
mpu.setI2CBypassEnabled(true);
mpu.setSleepEnabled(false);`
But still, it stuck at begin() again.

You still have to call mpu.begin before enabling the bypass. I have added to my answer some background information and how to test the second I2C bus.

Thank to Jot, your answer actually helps me.
Now I am using this code and it is working very well.
#include <Wire.h>
#include <HMC5883L.h>
#include <MPU6050.h>

HMC5883L compass;
MPU6050 mpu;

int previousDegree;

void setup()
{
  #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
        Wire.begin();
  #elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE
        Fastwire::setup(400, true);
  #endif
  Serial.begin(38400);

  // Initialize MPU6050
  mpu.initialize();

  // Enable bypass mode
  mpu.setI2CMasterModeEnabled(false);
  mpu.setI2CBypassEnabled(true);
  mpu.setSleepEnabled(false);

  // Initialize HMC5883L
  while (!compass.begin())
  {
    delay(500);
  }

  // Set measurement range
  compass.setRange(HMC5883L_RANGE_1_3GA);

  // Set measurement mode
  compass.setMeasurementMode(HMC5883L_CONTINOUS);

  // Set data rate
  compass.setDataRate(HMC5883L_DATARATE_30HZ);

  // Set number of samples averaged
  compass.setSamples(HMC5883L_SAMPLES_8);

  // Set calibration offset. See HMC5883L_calibration.ino
  compass.setOffset(0, 0);
}

void loop()
{
  long x = micros();
  Vector norm = compass.readNormalize();

  // Calculate heading
  float heading = atan2(norm.YAxis, norm.XAxis);

  // Set declination angle on your location and fix heading
  // You can find your declination on: http://magnetic-declination.com/
  // (+) Positive or (-) for negative
  // For Bytom / Poland declination angle is 4'26E (positive)
  // Formula: (deg + (min / 60.0)) / (180 / M_PI);
  float declinationAngle = (4.0 + (26.0 / 60.0)) / (180 / M_PI);
  heading += declinationAngle;

  // Correct for heading < 0deg and heading > 360deg
  if (heading < 0)
  {
    heading += 2 * PI;
  }

  if (heading > 2 * PI)
  {
    heading -= 2 * PI;
  }

  // Convert to degrees
  float headingDegrees = heading * 180/M_PI;

  // Fix HMC5883L issue with angles
  float fixedHeadingDegrees;

  if (headingDegrees >= 1 && headingDegrees < 240)
  {
    fixedHeadingDegrees = map(headingDegrees, 0, 239, 0, 179);
  } else
  if (headingDegrees >= 240)
  {
    fixedHeadingDegrees = map(headingDegrees, 240, 360, 180, 360);
  }

  // Smooth angles rotation for +/- 3deg
  int smoothHeadingDegrees = round(fixedHeadingDegrees);

  if (smoothHeadingDegrees < (previousDegree + 3) && smoothHeadingDegrees > (previousDegree - 3))
  {
    smoothHeadingDegrees = previousDegree;
  }

  previousDegree = smoothHeadingDegrees;

  // Output
  Serial.print(norm.XAxis);
  Serial.print(":");
  Serial.print(norm.YAxis);
  Serial.print(":");
  Serial.print(norm.ZAxis);
  Serial.print(":");
  Serial.print(headingDegrees);
  Serial.print(":");
  Serial.print(fixedHeadingDegrees);
  Serial.print(":");
  Serial.print(smoothHeadingDegrees);
  Serial.println();

  // One loop: ~5ms @ 115200 serial.
  // We need delay ~28ms for allow data rate 30Hz (~33ms)
  delay(30);
}

By the way, the code on https://github.com/jarzebski/Arduino-HMC5883L should add
  #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
        Wire.begin();
  #elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE
        Fastwire::setup(400, true);
  #endif

in the begin of setup.


text:
How can i stop DC motor when button on remote is released?
I am trying to control a motor using a remote with Arduino Mega. The motor turns on when I press the button on the remote but when I release the button, it continues to move. Does anyone know how to stop the motor spinning when I release the button on the remote?

IR remote? Those generally don't have the concept of button release.

do you actually have code to turn the motor off?   .... a lot of people assume that if the motor turns on when a button is pressed, that it will magically turn off when the button is released

share you sketch here.

You won't get answer more precise than Majenko's, until you share the code in question. Though it is a good answer.

For an infra-red remote control you generally can't. Those don't normally have the concept of button release.
Normally there are two kinds of buttons on a remote:

Burst code
Repeat code

The first sends a short burst of the same code. This allows for a function to be run once per button press.  The second sends the same code over and over again constantly until you release it.
For the repeat code buttons you can use that to your advantage.  You program your Arduino to run the motor for a short period. That period needs to be slightly longer than the time between each code reception. Then it can appear that it's responding to the release of the button.
For example, if your remote sends codes 5 times per second then whenever you receive a code you start the motor. If you haven't received a code for more than say 300ms then stop the motor.


text:
Multiplexing three VFD tubes — why are the segments and the display timing incorrect?
I'm using an Arduino Nano, a UNL2803 IC, and three 2N3904 transistors to drive three seven-segment vacuum fluorescent display tubes (IV-6) in a multiplex configuration. The UNL2803 is used to drive the segments: when an Arduino pin is pulled low, 25V is sent to the corresponding segment. The 2N3904 transistors are used to drive each of the digits: when the Arduino pin is high, 25V is sent to the digit's grid, thereby activating the digit.
The problem: the tubes aren't showing the correct segments, and the displays aren't being activated with correct timing. I have checked each segment connection to make sure it is connected to the correct segment. By slowing down the time interval between digits, I can see that the second and third digits (the 10s and 1s) are being displayed sequentially with the correct interval, but the first digit (the 100s) comes on with the second digit and stays on for twice the interval time. It also appears that some of the digits are attempting to display more than one number (sequentially) while activated.
The code:
// Pin assignments for segments
const int SEG_A = 2;
const int SEG_B = 3;
const int SEG_C = 4;
const int SEG_D = 6;
const int SEG_E = 5;
const int SEG_F = 7;
const int SEG_G = 8;

// Pin assignments for digits
const int DIG1 = 9;
const int DIG2 = 10;
const int DIG3 = 11;

int digit = 1;
int dig_number = 0;
unsigned int number = 321;

void setup() {

  Serial.begin(9600);

  // Set segment pins as outputs
  pinMode(SEG_A, OUTPUT);
  pinMode(SEG_B, OUTPUT);
  pinMode(SEG_C, OUTPUT);
  pinMode(SEG_D, OUTPUT);
  pinMode(SEG_E, OUTPUT);
  pinMode(SEG_F, OUTPUT);
  pinMode(SEG_G, OUTPUT);

  // Set digit pins as outputs
  pinMode(DIG1, OUTPUT);
  pinMode(DIG2, OUTPUT);
  pinMode(DIG3, OUTPUT);

  // Turn off digits
  digitalWrite(DIG1, LOW);
  digitalWrite(DIG2, LOW);
  digitalWrite(DIG3, LOW);
}

void loop() {
      if (digit == 1) {
        digitalWrite(DIG1, HIGH);
        digitalWrite(DIG2, LOW);
        digitalWrite(DIG3, LOW);
        dig_number = number / 100;
        if (number < 100) {      // to disable the digit if it's not being used
          dig_number == 99;      // triggers 'default' in switch/case
          display_number(dig_number);
        } else {
          display_number(dig_number);
        }
        digit = 2;
        Serial.println("The first digit is: ");
        Serial.print(dig_number);
        delay (250);
      }

      if (digit == 2) {
        digitalWrite(DIG1, LOW);
        digitalWrite(DIG2, HIGH);
        digitalWrite(DIG3, LOW);
        dig_number = (number / 10) % 10;
        if (dig_number == 0 && number < 10) {       // to disable the digit if it's not being used
          dig_number == 99;        // triggers 'default' in switch/case
          display_number(dig_number);
        } else {
          display_number(dig_number);
        }
        digit = 3;
        Serial.println("The second digit is: ");
        Serial.print(dig_number);
        delay (250);
      }

      if (digit == 3) {
        digitalWrite(DIG1, LOW);
        digitalWrite(DIG2, LOW);
        digitalWrite(DIG3, HIGH);
        dig_number = number % 10;
        display_number(dig_number);
        digit = 1;
        Serial.println("The third digit is: ");
        Serial.print(dig_number);
        delay (250);
      }
}

void display_number(int dig_number) {

    switch (dig_number) {
        case 0:
        digitalWrite(SEG_A, LOW);
        digitalWrite(SEG_B, LOW);
        digitalWrite(SEG_C, LOW);
        digitalWrite(SEG_D, LOW);
        digitalWrite(SEG_E, LOW);
        digitalWrite(SEG_F, LOW);
        digitalWrite(SEG_G, HIGH);
        break;

    case 1:
        digitalWrite(SEG_A, HIGH);
        digitalWrite(SEG_B, LOW);
        digitalWrite(SEG_C, LOW);
        digitalWrite(SEG_D, HIGH);
        digitalWrite(SEG_E, HIGH);
        digitalWrite(SEG_F, HIGH);
        digitalWrite(SEG_G, HIGH);
        break;

    case 2:
        digitalWrite(SEG_A, LOW);
        digitalWrite(SEG_B, LOW);
        digitalWrite(SEG_C, HIGH);
        digitalWrite(SEG_D, LOW);
        digitalWrite(SEG_E, LOW);
        digitalWrite(SEG_F, HIGH);
        digitalWrite(SEG_G, LOW);
        break;

    case 3:
        digitalWrite(SEG_A, LOW);
        digitalWrite(SEG_B, LOW);
        digitalWrite(SEG_C, LOW);
        digitalWrite(SEG_D, LOW);
        digitalWrite(SEG_E, HIGH);
        digitalWrite(SEG_F, HIGH);
        digitalWrite(SEG_G, LOW);
        break;

    case 4:
        digitalWrite(SEG_A, HIGH);
        digitalWrite(SEG_B, LOW);
        digitalWrite(SEG_C, LOW);
        digitalWrite(SEG_D, HIGH);
        digitalWrite(SEG_E, HIGH);
        digitalWrite(SEG_F, LOW);
        digitalWrite(SEG_G, LOW);
        break;

    case 5:
        digitalWrite(SEG_A, LOW);
        digitalWrite(SEG_B, HIGH);
        digitalWrite(SEG_C, LOW);
        digitalWrite(SEG_D, LOW);
        digitalWrite(SEG_E, HIGH);
        digitalWrite(SEG_F, LOW);
        digitalWrite(SEG_G, LOW);
        break;

    case 6:
        digitalWrite(SEG_A, LOW);
        digitalWrite(SEG_B, HIGH);
        digitalWrite(SEG_C, LOW);
        digitalWrite(SEG_D, LOW);
        digitalWrite(SEG_E, LOW);
        digitalWrite(SEG_F, LOW);
        digitalWrite(SEG_G, LOW);
        break;

    case 7:
        digitalWrite(SEG_A, LOW);
        digitalWrite(SEG_B, LOW);
        digitalWrite(SEG_C, LOW);
        digitalWrite(SEG_D, HIGH);
        digitalWrite(SEG_E, HIGH);
        digitalWrite(SEG_F, HIGH);
        digitalWrite(SEG_G, HIGH);
        break;

    case 8:
        digitalWrite(SEG_A, LOW);
        digitalWrite(SEG_B, LOW);
        digitalWrite(SEG_C, LOW);
        digitalWrite(SEG_D, LOW);
        digitalWrite(SEG_E, LOW);
        digitalWrite(SEG_F, LOW);
        digitalWrite(SEG_G, LOW);
        break;

    case 9:
        digitalWrite(SEG_A, LOW);
        digitalWrite(SEG_B, LOW);
        digitalWrite(SEG_C, LOW);
        digitalWrite(SEG_D, LOW);
        digitalWrite(SEG_E, HIGH);
        digitalWrite(SEG_F, LOW);
        digitalWrite(SEG_G, LOW);
        break;

    default:
        digitalWrite(SEG_A, HIGH);
        digitalWrite(SEG_B, HIGH);
        digitalWrite(SEG_C, HIGH);
        digitalWrite(SEG_D, HIGH);
        digitalWrite(SEG_E, HIGH);
        digitalWrite(SEG_F, HIGH);
        digitalWrite(SEG_G, HIGH);
        break;
    }
}

The circuit diagram:

I have heard rumor that using delay() instead of millis() for multiplexing can be problematic. Is that what's going on here?
Many thanks in advance for considering this problem!

The way you have wired ìt, when you are switching a digit on, you need to send a LOW to its corresponding pin and a HIGH to the other two digit pins. You have this inverted. I'm guessing that the wire connecting R9, R10 and R11 goes all the way to 25 volts. Base resistors on the transistors would be nice.

Thank you. My understanding of using the 2N3904 transistor as a switch is that a high pin is needed on the base in order to "open" the switch and allow current to flow from collector to emitter. Please help me understand the need for a low pin on the base for this to work. I am new to transistors. :)

This is correct but, in your case, switching the transistors on pulls the grids to ground thus switching off the displays. I have added a more complete explanation below as an answer.

For future searchers, you can check out the final project here. Many thanks to those who commented——your feedback was extremely helpful.

Your code appears to invert the switching pattern of the digits. Instead of switching the  selected digit on and the other two off, you are doing the opposite.
The grid of a VFD tube has to have a voltage applied to it to illuminate the selected segments. Those segments are also selected by having a voltage applied. The circuit you have shown, by default, powers both the grids and the segments via 10k resistors connected to the 25 volt power rail. The transistors, also in the uln2803, when switched on, pull the grids and segments to ground, thus switching those elements off. This arrangement reduces the complexity of the circuit by eliminating the need for high side switching but "wastes" power.
A simple code correction should solve the problem:
// Turn off digits
   digitalWrite(DIG1, HIGH);  // high turns the grid off.
   digitalWrite(DIG2, HIGH);
   digitalWrite(DIG3, HIGH);
 }

if (digit == 1) {
   digitalWrite(DIG1, LOW);  // digit one ON
   digitalWrite(DIG2, HIGH); // digit two OFF
   digitalWrite(DIG3, HIGH); // digit three OFF
}

Do the equivalent for digits 2 and 3.
Use resistors (say 1k) in series with the transistor bases to limit the current and protect the arduino pins. See https://learn.sparkfun.com/tutorials/transistors/applications-i-switches
You still have to confirm if the wire connecting R9, R10 and R11 goes to all the way to the +25 volt rail. This is not clear from the schematic.

Thanks so much for this explanation! I eventually replaced the 2N3904 transistors with a ULN2803, and that fixed the problem. All is working as it should now, except for one small quirk: I have set up a simple counter to cycle through numbers, and I can see very faint illumination on segments that are not energized while the count is underway. A "ghosting" effect, so to speak, on all the digits. Very low voltage is somehow getting to pins that are not selected. Any idea where this might be coming from?

@ThomasBurns If you get ghosting, then before switching one digit on, first switch the other two off, then set up the segments (by calling display_number() ) and wait say 1ms. Then switch the selected digit on.  Also, speed up your multiplexing. Probably display each digit for about 5ms to avoid noticeable flicker but without incurring too much of a switching loss penalty. This means a small restructuring of your code.

Yes this worked (had to tinker with it for a few minutes). Many thanks for the feedback!

I made a VFD clock using some really cool old DG10B tubes from an early calculator a year or so ago. I had a heck of a time getting it to work, until I decided try tackling one problem at a time, and then put it all together.
In my clock I used the MAX6921 VFD driver IC, a DS3231 RTC with super cap, and a XIAO for the brains. The VFD driver chip is controlled by pwm/serial (data, load, clock) and the RTC is over I2c.
Instead of trying to multiplex them, I just got them all working at once, I did a nice slow count of all digits being on and displaying the same digits. This helped me detect a couple wiring faults, and helped me figure out which segments needed to be lit for each number I wanted displayed. (the digits on my tubes are quite unique!)

once I had my "fonts" figured out and a case for each digit, I created a simple loop that counted through 0-9 on all digits with all four of them on. 4444, 5555, etc
Then I started trying to get just one digit lit at a time.  (this helped me find another wiring issue)
// [pihgfedcba------1234}; //this is what the data stream looks like when sent to the driver
// ...where the first 10 digits are the segments, and the last 4 are the grids for each digit from left to right 1-4.
// The rest are currently unused and should be padded with zero's or 1's)
Next I made a loop that would check the time, and print out the digits. I DO use delay() in my code, in order to deliberately flicker my tubes (for the antique steampunk effect)
But here's the thing, I believe my code checks the time for each individual digit.
the loop says for each digits 1-4 (check time, display digit)
there was a lot more involved, and it's been a while since I worked on it so I am not sure I am being helpful here.  I just wanted to suggest you follow a good troubleshooting process. (smaller problems are easier to solve)

This was extremely helpful. Your approach led me to discover that I was using an incorrect pinout for the UNL2803 chip. Correcting this solved my segment problems. Still working on figuring out what's going on with the digits. Thank you! Also wanted to quickly say that your breadboard technique is inspiring—mine looks considerably less organized.

Haha, yeah, my bread boarding is a little obsessive.   -and I'm  glad I was able to help.  Vfd displays are so fascinating. Hope your project turns out how your want envision it. :)

I'd love to get my hands on some of those VFD tubes with their rough, handwritten style  fonts. But, I know, such odd ball displays are difficult to get hold of and probably well outside any reasonable hobby budget.

For future searchers, I finally got this circuit going using two ULN2803 transistor arrays, instead of discrete transistors for the digit connections. Here's the final schematic:

You can check out more about the final project here. Many thanks to those who commented——your feedback was very helpful!

your final schematic has still errors.
You fixed the missing GND to the ULN2803 drivers.
But the COM inputs (pin 10) and the three resistors for the grid shall be connected to +24V!

@Landroval Thanks for pointing this out! I've exchanged the schematic for the corrected version.


text:
LED array flashes once before being lit
I've built this simple Arduino controlled led-array. The Arduino sets a 5v pin on a relay to connect the high current power supply to a led array.
However, just before the led array is being fully turned on I'm getting this fast flash of the led array. I really would like to have the led working in an "on/off" manner.

I remember that working with some motors one have to use capcitator in parallel because of resistence drop. Is it also the case with led array? And if it is why so, and why a capcitator would help?
Thank you very much.

Does this flash only happen once each time the Arduino is 'booted'? If so, the issue may be the "power on" disposition of the Arduino pin that allow the LEDs to come on for a bit before the Arduinos pin is "configured".

Hi Wendeall,
No it happens every time to pin connected to the realy is set to "HIGH".

What led array are you using? What power supply are you using for this array?

The relay information shows this relay requires over 70ma to latch at 5 volts. The Arduino can only -maybe- provide half of that. Why it is working at all I don't know. Just as  Duncan C suggested, you are going to have to use a driver circuit (there are many designs, search for "Arduino relay driver") to correctly operate the relay. Then the "flash" will probably go away too.

Don't you use the matrix' SPI? If so, how do you know that it is supposed to work without, have you tried? Even if it's simple code you should add it, so we don't have to guess if there are mistakes. Also a link to the led matrix might be helpful

As Wendall says in his comment, you probably have an issue with the power-on state of your logic pins before the Arduino finishes booting up.
In addition to that, you should not drive a relay directly from an Arduino logic pin, for a couple of reasons:

It can't provide enough current to drive a relay coil.
The relay emits a strong surge of reverse current when you switch it off. This will likely destroy the logic pin you are using to drive the relay, or it might even destroy the whole Arduino board.

For these reasons you should drive the relay using a transistor, and you should put a properly sized diode wired across the relay coil backwards from the flow of current when the relay is energized. The diode bleeds off the reverse current from the relay coil.

Thanks a lot Duncan.
I'm using this relay:
http://www.circuitbasics.com/wp-content/uploads/2015/11/SRD-05VDC-SL-C-Datasheet.pdf
Which suppose to be activated using a 5V pin. I would definitely try adding a diode to stop the reverse current.
However, the fast blink happens every time I close the relay circuit (turn on the led). There's one fast blink before the led is being activated.

Ok, it sounds like you're using a "solid state relay", which has built-in circuitry to drive the relay coil from a low power logic line, while protecting the logic line from the "raw" relay. (If so it might have a transistor and protection diode in it already.) You might want to edit your question and post details on the type and setup of the relay you're using.


text:
'myservo' does not name a type
I keep getting 'myservo' does not name a type as an error message, I have already looked other solved questions like this one but I can´t find the mistake. I would be very glad for your help.
/*********************************************************
 * Bot control
 * By soleil_zero
 * Based on code by
 * MSc. Fausto M. Lagos S.
 * @piratax007
 * V2.0.0 - 2019
 * GNU GPLV3+
 *
 * Hardware:
 * Arduino Mega2560
 * Adafruit Motor Shield V1.2
 * Bluetooth module H6
 * 1 Servo
 * 2 DC Motor
 *********************************************************/

// Librería para Adafruit Motor Shield V1.2 y Servo
#include "AFMotor.h"
#include "Servo.h"

// Motores conectados en los puertos 1 y 2
AF_DCMotor leftMotor(1, MOTOR12_64KHZ);
AF_DCMotor rightMotor(2, MOTOR12_64KHZ);

Servo myservo;
myservo.attach(9);

// Variable para el paso de mensajes vía Bluetooth
char message;
//ángulo de rotación del servo
int angle = 0;

void setup() {
  // Velocidades en los motores
  leftMotor.setSpeed(150);
  rightMotor.setSpeed(150);

  /* Debido a que el Adafruit Motor Shield V1.2 ocupa los pines digitales 0 y 1 para la conexión del módulo HC05
     bluetooth deben utilizarse cualquiera de los otros disponibles: 14 (TX3) y 15 (RX3) o 16 (TX2) y 17 (RX2) o
     18 (TX1) Y 19 (RX1). De acuerdo a cuál de los cuatro pines se utilicen deben modificarse las líneas
     relacionadas a la comunicación Serial e.g si se utilizan los pines 18 y 19 la instrucción será Serial1 */
  Serial3.begin(9600);
  myservo.write(angle);
}

void loop() {
  // Verificación de mensaje en el puerto Serial
  if (Serial3.available() > 0) {
    message = Serial3.read();
  }

 if (message == 'F') {//Forward
    leftMotor.run(FORWARD);
    rightMotor.run(FORWARD);
  } else if (message == 'B') {//Backwards
    leftMotor.run(BACKWARD);
    rightMotor.run(BACKWARD);
  } else if (message == 'L') {//Left
    leftMotor.run(FORWARD);
    rightMotor.run(BACKWARD);
  } else if (message == 'R') {//right
    leftMotor.run(BACKWARD);
    rightMotor.run(FORWARD);
  } else if (message == 'S') {//stop
    leftMotor.run(RELEASE);
    rightMotor.run(RELEASE);
    Serial3.print("stop");
  }
  } else if (message == 'U') {//down
    angle = 0;
    servo1.write(angle);
  }else if (message == 'D') {//up
    angle = 90;
    servo1.write(angle);
  }
}

this has been asked a lot ... please do research before posting your question

In C and C++ languages we write statements inside functions. That myservo.attach(9); is a statement. You can't just write it in the middle of the file. It has to reside inside a function.
In your code myservo.attach(9); just sits in the middle of nowhere. You had enough sense to put leftMotor.setSpeed(150); inside setup(). Why did you suddenly decide to place myservo.attach(9); outside of any functions?
Function setup() would be an appropriate place for this statement.


text:
How to send HTTP requests using wifi of Arduino Primo board?
I have bought an Arduino Primo board. I have configured it to connect to my wifi router and changed it to STA mode. Now, how do I program it to send HTTP requests to a server? Which library file I should use? Any tutorial?

With Arduino Primo use the WiFi Link library. Look at WiFi Link Examples in IDE menu.
Arduino org web archive pages

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


text:
Where is JP1 on the Arduino Uno?
Recently I have been attempting to make my Arduino Uno a PIC16F877A programmer. Looking at the schematic to do this, I see that there is no JP1 pin on the Arduino as specified on the diagram on the top-left.

As I am new to electrical engineering I may just be simply overlooking it yet this is unlikely because I have been puzzled by this for two days.

JP1 is not a pin. It is a connector, with, if my eyes still work, 2 pins, which look like 13 volt DC and Ground. Likewise JP2 is not a pin, but a connector, with, hmmm, 6 pins. Three of which go directly to the Arduino, another one to the Arduino via Q1, and a final pin to Ground.

None of this is on the Arduino. You must construct all of this yourself.

I'm talking about the pins. If you notice to the left it says "Connections to arduino" and these pins do exist, for instance the A1 pin. Please do research before giving an answer.

Notice how the green box starts a bit above A1 and stops a bit below D4? Care to hazard a guess why?

Hint: JP1 is not a pin. It is a connector, with, if my eyes still work, 2 pins, which look like 13 volt DC and Ground. Likewise JP2 is not a pin, but a connector, with, hmmm, 6 pins. Three of which go directly to the Arduino, another one to the Arduino via Q1, and a final pin to Ground.

Thank you for the answer @dda. Please post your comment as an answer so I can accept it.

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


text:
AI A7 Thinker connection with Arduino
I am trying to connect my A7 to my Arduino Uno but I can't find a way to communicate with it. I searched a lot on the internet to find some schemes but not one of them worked. Here is my actual setup:
ARDUINO              A7

PIN 6      <=>       URXD
PIN 7      <=>       UTXD
GND        <=>       GND
5V         <=>       5V

Here is my code:
#include<SoftwareSerial.h>
SoftwareSerial myserial(6,7);//RX,TX

void setup() {
  Serial.begin(9600);
  myserial.begin(115200);
  Serial.println("Starting...");
}

void loop() {
   delay(1000);
   myserial.println("AT");
   Serial.println(myserial.read());
}

I tried by connecting USB instead of 5V, both of them, connecting the POWER pin, or interchange 6 and 7, pressing the power button, with different delays, different baud rates, but I always get the same output on my computer:
Starting...
-1
-1
-1
-1
...

Sometimes it goes 0 when I plug the USB and press the power button. The LED on the A7 is responding when I press the button and sometimes it powers up the circuit.
I also tried this solution with really simple code:
void setup() {
   Serial.begin(115200);
}

void loop() {
}

Again with different bauds rates but the compiler outputs an error:
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 1 of 10: not in sync: resp=0x00
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 2 of 10: not in sync: resp=0x00
avrdude: stk500_recv(): programmer is not responding
...

So I don't know what is wrong. Maybe the board is not working but it's most certainly my mistake, so I am asking for your help to solve this puzzle.
Thank you!

I have no knowledge of an A7, but it looks that you have the RxTx of the serial link as 6 & 7 respectively and on the A7 you have connected 6 to Rx and 7 to Tx.  Normally when a board has a pin marked Tx its means Its Tx pin, so you should connect the A7's Tx pin to 6 and Rx to 7.  The programmer from PC to Uno should use pins 0 and 1.

Quite a few people using A7 and Arduino and working thru challenges at: https://forum.arduino.cc/index.php?topic=445548.0

I'm dealing with the exact same thing right now trying to get mine to work. The only help I can give so far is that that avrdude error was solved for me when i stopped trying to upload code to the uno with the a7 powered. think it has to do with the programmer using the same RX/TX ports.

What is an A7? Is that a board type?

You said...
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 1 of 10: not in sync: resp=0x00
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 2 of 10: not in sync: resp=0x00
avrdude: stk500_recv(): programmer is not responding

Those errors are occurring because you are attempting to upload to your Arduino using the same Tx/Rx wires that the software is using and trying to upload on.
A Possible Fix
You need to power down the A7.  Possibly pull the ground wire from it when you go to upload your program.  There are alternatives to doing this that are better, but the point is that the A7 is using those wires and keeping them busy.  If the A7 if off then the upload should work.  After uploading, then re-connect the A7 ground wire so it gets power.


text:
Using SPI and 2 shift registers WITHOUT libraries
Arduino Mega 2560 board and SN74HC595 shift register(s). I'm working on a school assignment and having issues getting the shift register(s) working without using Arduino libraries.
I know with the libraries you can use functions such as digitalWrite(....); and shiftOut(dataPin, clockPin, MSBFIRST, bitsToSend);.
For my project, I've set up my individual pins as inputs and outputs, but I am having trouble converting the library code into basic code.
IE:
digitalWrite(latchPin, LOW);

can be rewritten as
DDRB &= ~(1 << DDB1);

where latchPin is the SCK pin.
At this stage in the project, we're just trying to get 8 LEDs lit up using 1 shift register, then 16 using 2 shift registers. Any help in understanding what I need to do or direction in which to look would be appreciated.
Thank you,
Nic
Edit:
This is what I have converted from the void setup from https://www.arduino.cc/en/Tutorial/ShftOut12 :
void setup() {
  //Clear the shift registers prev data, Need a low input to reset registers
  //PORTL0 to first SReg SRCLR, PORTL2 to second SReg SRCLR
  //* See data sheet for sn74hc595 shift registers
  DDRL &= ~((1 << PORTL0) | (1 << PORTL2)); //Pg 100 - 21.2.3
  //Use port L0/L2 for SRCLR pin on SReg
  PORTL |= (1 << PORTL0) | (1 << PORTL2); //Pg 100 - 21.2.3

  //Set OE (Enable) to 0 until after last bit is sent
  DDRL &= ~(1 << PORTL4); //Pg 100 - 21.2.3
  //TODO SPI DELAY HERE USING SPDR pg 199

  //Enable SCK as output to drive RCLK and SRCLK on SR
  DDRB &= ~(1 << DDB1); //Pg 96 - 13.4.6
  PORTB |= (1 << PORTB1); //Pg 96 - 13.4.5

  //Enable MOSI as output to drive SER Input on SR
  DDRB &= ~(1 << DDB0); //Pg 96 - 13.4.6
  PORTB |= (1 << PORTB0); //Pg 96 - 13.4.5

  Serial.begin(9600);
  Serial.println("reset");
}

You mention “SPI” in the title, but you are not using the SPI port at all: you are bit-banging. Is this by choice?

The main problem you seem to have is how to implement shiftOut. Well, that's actually quite simple once you understand how shiftOut actually works.
You already know how to set a pin HIGH or LOW - all you lack from that is the concept of time.
All shiftOut does is set the clock and data pins HIGH and LOW at the right time.
It's simply a case of:

Set the DATA pin to HIGH or LOW depending on the bit value to send
Set the CLOCK pin HIGH
Set the CLOCK pin LOW
Go back to 1 for 8 iterations total.

Getting the bit value from a byte can be done with boolean operators & and <<
The basic shiftOut code looks like this:
void shiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, uint8_t val)
{
    uint8_t i;

    for (i = 0; i < 8; i++)  {
        if (bitOrder == LSBFIRST)
            digitalWrite(dataPin, !!(val & (1 << i)));
        else
            digitalWrite(dataPin, !!(val & (1 << (7 - i))));

        digitalWrite(clockPin, HIGH);
        digitalWrite(clockPin, LOW);
    }
}

Since your bit order is fixed you can reduce that down to this:
void myShiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t val)
{
    uint8_t i;

    for (i = 0; i < 8; i++)  {
        digitalWrite(dataPin, !!(val & (1 << (7 - i))));
        digitalWrite(clockPin, HIGH);
        digitalWrite(clockPin, LOW);
    }
}

And then you can replace your digitalWrite calls with direct register manipulation.
void myShiftOut(uint8_t val)
{
    uint8_t i;

    for (i = 0; i < 8; i++)  {
        if (val & (1 << (7 - i))) {
            PORTB |= (1 << PORTB0);  // Data 1
        } else {
            PORTB &= ~(1 << PORTB0); // Data 0
        }
        PORTB |= (1 << PORTB1);      // Clock HIGH
        PORTB &= ~(1 << PORTB1);     // Clock LOW
    }
}

Note that this code will now run considerably faster than the bloaty digitalWrite based version - so you may find it's now too fast. You may need to include some short delays around the clock HIGH and clock LOW lines. Depending on how long they need to be you could write a little delay loop to introduce a short delay:
void delayLoop(uint32_t iterations) {
    while ((--iterations) > 0) {
        asm volatile("nop");
    }
}

That will delay for iterations clock cycles plus the time taken to do the loop and call the function.  For very short delays it may be better to just insert a few nop instructions:
PORTB |= (1 << PORTB1);      // Clock HIGH
asm volatile("nop");
asm volatile("nop");
asm volatile("nop");
PORTB &= ~(1 << PORTB1);     // Clock LOW
asm volatile("nop");
asm volatile("nop");
asm volatile("nop");

For delaying, you can also #include <util/delay.h> and then _delay_us(0.25) for example.


text:
Can I have two separated serial monitor for the same arduino board connected to PC?
I'd like to split serial communication into the two channels: 1) debug info, 2) application data.
There's only one Serial object to use.
However, maybe, there is an alternative way to print data separately, is there?
P.S. I use Nano and UNO.

There is the SoftwareSerial Library: https://www.arduino.cc/en/Reference/SoftwareSerial, https://www.arduino.cc/en/Tutorial/TwoPortReceive.

can you give more info on what device you are using, and what you are actually trying to accomplish

I specified boards I use and the purpose I'm pursuing.

@VE7JRO, Thanks for the answer. But how to see the output from two serial ports of the the same arduino board on the same computer?

In windows you need to open one instance via "run as administrator" and the other one as the standard user. This way the two instances don't know of each other and you can adjust the com port separately. Cheers

@JochenReitzig, it can be started twice with double click on a desktop icon. no need for "as asdministrator"

As Majenko mentioned in his answer, you can connect a USB to UART adaptor such as a PL2303HX to your Uno (cost is $0.70 CDN). Just connect the RX, TX, GND pins to your Arduino correctly and include the SoftwareSerial Library in your sketch.
Here is a simple test sketch which is almost identical to the "SoftwareSerialExample" that comes with the SoftwareSerial Library.
#include <SoftwareSerial.h>

SoftwareSerial mySerial(10, 11); // RX, TX

void setup(){
  Serial.begin(9600);
  Serial.println("Print to Serial Monitor");
  mySerial.begin(9600);
  mySerial.println("Print to SoftwareSerial");
}

void loop(){
  if(mySerial.available()){
    Serial.write(mySerial.read());
  }
  if(Serial.available()){
    mySerial.write(Serial.read());
  }
}

If you want to have two Serial Monitors, start the IDE twice. Use your desktop shortcut or start menu entry to start the second instance of the IDE. In the second instance you can select a different port. It will not work for Upload of course, but when you open the Serial Monitor, it will work at the selected port.
Other option is to use some terminal program to see the output of the com port.
The other answers cover the fact that you need an USB to TTL Serial adapter to connect to USB and in sketch SoftwareSerial as your second serial interface or use some board with two or more hardware serial ports like the Mega on the picture.

spot on.  I have a device which uses a nodemcu & an Arduino nano and i monitor each on a separate instance of Arduino IDE

You can add another channel with the SoftwareSerial library and an FTDI cable. The cable costs about US$17 in the US and is available here from Amazon, Sparkfun, and probably others. Internationally, I don't know. The SoftwareSerial library does have some limitations, most notably that it has to interrupts off while it's actually operating to get its baud rate right. But it does work and may be the simplest solution for you.

Depending on your software environment, the simplest thing may be to
send all the data multiplexed through the single serial port, then split
it into two channels at the other end. For that, you will need some sort
of multiplexing protocol. If all your data is text and line oriented,
this may be as simple as prefixing each line with "1" or "2" to select
the appropriate channel:
Serial.println("1This app data goes to stdout.");
Serial.println("2This diagnostic message goes to sterr.");

If you want to send arbitrary byte streams, you would instead use two
control characters for selecting the channels and an "escape" character
for when you want the control characters to be transmitted literally.
For convenience, you could encapsulate this logic into two separate
objects and implement stdout.println() and stderr.println().
Then on the computer side, you will have to write a program that reads
the serial port and splits the received bytes into two separate streams.
How you implement those streams is OS-dependent. On an Unixish system I
would probably use pipes, or pseudo-terminals if I needed bidirectional
communication.

Not without adding more hardware, no.
You could add a usb to UART adapter and use software serial. Better would be to switch to a board that has a proper usb connection and a usb stack that supports multiple CDC/ACM instances, like a chipKIT board (Lenny, for instance).

Disclaimer: I designed the Lenny (though I only profit from it if you buy it from me) and I designed the usb stack specifically so you can have multiple instances of the different drivers.

one can actually use 2 separate USB ports, one for each device and run the IDE twice, as Juraj pointed out

@tonygil You mean like where I say "You could add a usb to UART adapter and use software serial."...?


text:
Using TXD1/RXD1 on ATmega1280 for USB communication
I have a few MakerBot Mightyboards running off ATmega1280 chips that can no longer use their standard USB port to connect to a computer (to make a long story short, there's a little inductor that blew up between the USB port and the 8u2 chip and it is essentially impossible to replace). I have noticed, however, that they have headers for the RXD1 (PD2) and TXD1 (PD3) pins on the 1280 as seen in this picture:

Would it be possible to hook up an external 8u2 (or similar) chip programmed as a USB to serial converter (something like this) and use it as if it were the normal USB port (e.g. for uploading firmware)?
(I wanted to add atmega1280 as a tag, but it doesn't seem to exist)

How on earth did you manage to blow up a resistor?!?!?!

Just noticed I actually got mixed up and the parts I'm talking about are inductors. They're tiny surface-mounted ones, and they're placed right next to the USB port. The boards are quite old (about 5 years) so I'm guessing a slight power surge over USB caused them to literally blow up (there's burn marks on the boards that have this).

Not directly, no.
The USB interface connects to TX0 and RX0 - you have access to TX1 and RX1. The bootloader is set to look at TX0 and RX0.
You would have to compile and install a new version of the bootloader that is set to use TX1 and RX1.

Thanks! I highly doubted it would work out-of-the-box like that. Do you happen to know what changes I would have to make to the bootloader for this to work (and where I could get said bootloader)?

No idea, I have never compiled the bootloader. I think there's something included with the IDE somewhere. Or Google optiboot as an option.

Alright, I'll try that out. It might take a while though since I'm waiting on parts. I'll make sure to post any new info I might have.


text:
Using 4 identical sensors on the I2C bus
I am using 4 Pololu VL6180X ToF sensors on the Arduino UNO for a school project but just can't seem to get it working correctly. I understand that I need to hold them in reset and change the I2C address of each sensor after waking them up, but the code I have doesn't work. Is the problem some flawed understanding of the C language?
This is the .h file I wrote (distSensors.h):
/*
This module is used to interface with the distance sensors.
*/
#ifndef DISTSENSORS_FILE
#define DISTSENSORS_FILE

#include "vl6180x/VL6180X.h"
#include "globals.h"

// pins connected to VL6180 GPIO used to hold sensor in reset
#define NORTH_SHUTDOWN 13
#define EAST_SHUTDOWN 1
#define WEST_SHUTDOWN 0

// threshold distance for detectWall (mm)
double const WALL = 70;

// initializes sensor
void initSensor(VL6180X* sensor) {
  (*sensor).init();
  (*sensor).configureDefault();
  (*sensor).setTimeout(500);
}

void changeAddress(VL6180X* sensor, int address) {
  (*sensor).setAddress(address);
}

// sensors
VL6180X sensorNorth;
VL6180X sensorSouth;
VL6180X sensorWest;
VL6180X sensorEast;

void setupSensors() {
  // shutdown pins
  pinMode(NORTH_SHUTDOWN, OUTPUT);
  pinMode(WEST_SHUTDOWN, OUTPUT);
  pinMode(EAST_SHUTDOWN, OUTPUT);

  // hold each sensor in shutdown initially
  digitalWrite(NORTH_SHUTDOWN, LOW);
  digitalWrite(WEST_SHUTDOWN, LOW);
  digitalWrite(EAST_SHUTDOWN, LOW);
  delay(10);

  digitalWrite(NORTH_SHUTDOWN, HIGH);
  digitalWrite(WEST_SHUTDOWN, HIGH);
  digitalWrite(EAST_SHUTDOWN, HIGH);

  digitalWrite(NORTH_SHUTDOWN, LOW);
  digitalWrite(WEST_SHUTDOWN, LOW);
  digitalWrite(EAST_SHUTDOWN, LOW);

  // wake sensors and change address one by one
  // south is never shutdown, and its address is changed first
  changeAddress(&sensorSouth, 0x23);
  delay(10);

  digitalWrite(WEST_SHUTDOWN, HIGH);
  changeAddress(&sensorWest,0x25);
  delay(10);

  digitalWrite(EAST_SHUTDOWN, HIGH);
  changeAddress(&sensorEast, 0x27);
  delay(10);

  digitalWrite(NORTH_SHUTDOWN, HIGH); // NORTH maintains default address

  // init all sensors
  initSensor(&sensorNorth);
  initSensor(&sensorSouth);
  initSensor(&sensorWest);
  initSensor(&sensorEast);
}

// Return the distance reading from the given direction
double getDist(int direction) {
  switch (direction) {
  case NORTH:
    return sensorNorth.readRangeSingleMillimeters();
  case SOUTH:
    return sensorSouth.readRangeSingleMillimeters();
  case WEST:
    return sensorWest.readRangeSingleMillimeters();
  case EAST:
    return sensorEast.readRangeSingleMillimeters();
  }
}

// return 1 if there is a wall, 0 if there is not a wall
int detectWall(int direction) {
  if (getDist(direction) <= WALL) { return 1; }
  else { return 0; }
}

#endif

And this is the test code I'm running:
#include "distSensors.h"
#include "Wire.h"
void setup() {
  // put your setup code here, to run once:
  Wire.begin();
  setupSensors();
  Serial.begin(9600);
}

void loop() {
  // put your main code here, to run repeatedly:
  Serial.print("NORTH: "); Serial.println(getDist(NORTH));
  Serial.print("SOUTH: "); Serial.println(getDist(SOUTH));
  Serial.print("WEST: "); Serial.println(getDist(WEST));
  Serial.print("EAST: "); Serial.println(getDist(EAST));
  delay(100);
}

getDist returns 0.0 for every sensor except for sensorSouth.
Any help would be greatly appreciated, thanks!

When coming out of hardware standby (reset) you need to provide time for the internal MCU in the VL6180X to boot up. Add a short delay between your HIGH and your changeAddress. Only a couple of milliseconds should do it.

After changing the i2c address, is that address stored in the sensor? Should it be set every time at startup? The pololu module has the recommended 47k resistor for gpio0/ce. When you put a 5v signal on that line the sensor might be damaged. That means at this moment all of those sensors might be broken. The module has a level shifter for sda and scl, but not the gpio0/ce pin. You should change the Arduino pin between output/low and input.

Might want to read: http://www.st.com/content/ccc/resource/technical/document/application_note/b4/f0/79/ec/ca/54/45/07/DM00114403.pdf/files/DM00114403.pdf/jcr:content/translations/en.DM00114403.pdf


text:
Serial monitor constantly reads input with unknown characters
I am trying to read input from the serial monitor on my Arduino UNO using the new Arduino IDE 2.0 and send a specific infrared signal depending on the command.
I do this using the following code:
#include <Arduino.h>

/*
 * Define macros for input and output pin etc.
 */
#include "PinDefinitionsAndMore.h"
#include <IRremote.h>

void setup() {
    pinMode(LED_BUILTIN, OUTPUT);

    Serial.begin(115200);
    while(!Serial) ;

    // Just to know which program is running on my Arduino
    Serial.println(F("START " __FILE__ " from " __DATE__ "\r\nUsing library version " VERSION_IRREMOTE));

    /*
     * The IR library setup. That's all!
     */
    IrSender.begin(IR_SEND_PIN, ENABLE_LED_FEEDBACK); // Specify send pin and enable feedback LED at default feedback LED pin

    Serial.print(F("Ready to send IR signals at pin "));
    Serial.println(IR_SEND_PIN);
    Serial.println("Commands: start, stop, links, rechts, heim, max");
}

/*
 * Set up the data to be sent.
 * For most protocols, the data is build up with a constant 8 (or 16 byte) address
 * and a variable 8 bit command.
 * There are exceptions like Sony and Denon, which have 5 bit address.
 */
uint16_t sAddress = 0x5540;
uint8_t sCommand_Start_Stop = 0x44;
uint8_t sCommand_Left = 0x44;
uint8_t sCommand_Right = 0x44;
uint8_t sCommand_Home = 0x44;
uint8_t sCommand_Max = 0x44;

uint8_t sRepeats = 1;

bool is_running = false;
String command;

void loop() {
  if(Serial.available()){
        command = Serial.readStringUntil('\n');

        Serial.print(F("Command received: "));
        Serial.println(command);

        if(command.equals("start")){
            sendIRCommand(sAddress, sCommand_Start_Stop);
            is_running = 1;
        } else if(command.equals("stop")){
            sendIRCommand(sAddress, sCommand_Start_Stop);
            is_running = 0;
        } else if(command.equals("links")){
            sendIRCommand(sAddress, sCommand_Left);
        } else if(command.equals("rechts")){
            sendIRCommand(sAddress, sCommand_Right);
        } else if(command.equals("heim")){
            sendIRCommand(sAddress, sCommand_Home);
        } else if(command.equals("max")){
            sendIRCommand(sAddress, sCommand_Max);
        } else{
            Serial.println("Invalid command!");
        }
    }
}

void sendIRCommand(int irAddress, int irCommand) {
  /*
     * Print current send values
     */
    Serial.println();
    Serial.print(F("Send now: address=0x"));
    Serial.print(irAddress, HEX);
    Serial.print(F(" command=0x"));
    Serial.print(irCommand, HEX);
    Serial.println();

    Serial.println(F("Send NEC with 16 bit address"));
    Serial.flush();

    IrSender.sendNEC(irAddress, irCommand, sRepeats);
}

In the process I encounter the problem that the serial monitor constantly reads unknown characters as alleged inputs, although I don't send anything. Because of the two unknown characters, even the proper commands can't be recognized correctly, which is a big problem. Here is the extract of the serial monitor:
15:53:42.987 -> START c:\PATH\TO\SCRIPT\command-sender.ino from Aug 16 2021
15:53:45.093 -> Using library version 3.1.1
15:53:45.094 -> Ready to send IR signals at pin 3
15:53:45.096 -> Commands: start, stop, links, rechts, heim, max
15:53:45.100 -> Command received: ��
15:53:47.107 -> Invalid command!
15:53:47.107 -> Command received: ��
15:53:49.122 -> Invalid comma��
15:53:49.122 -> Command received: ��
15:53:50.113 -> Invalid command!
15:53:50.117 -> Command received: ��
15:53:52.131 -> Invalid command!
15:53:52.131 -> Command received: ��
15:53:54.131 -> Invalid command!
15:53:54.131 -> Command received: ��
15:53:56.142 -> Invalid command!
15:53:56.142 -> Command received: ��
15:53:57.142 -> Invalid co+���Command received: ��
15:53:58.147 -> Invalid command!
15:53:58.147 -> Command received: ��start
15:53:58.932 -> Invalid command!
15:53:58.933 -> Command received: ��
15:54:00.950 -> Invalid command!

I checked the baudrate, use Serial.print and wait in the setup until the serial is initialized before I send data. I use 115200baud in the serial monitor in the IDE as well as New Line. All without success. How can I fix this problem?
Here is the URL for the PinDefinitionsAndMore.h if this is the root of the problem.
Update
When using VisualStudio Code with the PlatformIO extension, sending the commands works just fine. Here the unknown characters don't show up neither. It almost seems like the problem is related to the Arduino IDE 2.0 in some way.

did you wired something to pin 0 or 1?

@Juraj No, pin 0 + 1 are not used. There is also no physical connection of the two pins on the back of the board. Pin 2 + 3 are used for sensors

Can you please replace Serial.println(command); by Serial.println(command, HEX); and then post the serial output again. That should at least show us, what data is actually received.

@chrisl, Serial.println(command, HEX)???

did you try the not Beta version of Arduino IDE? version 1.8.15

Oops, that is really wrong. More like for(int i=0;i<command.length();i++){ Serial.print(command[i], HEX);} Serial.println(); Wanted to print each character as hex to also identify the non-printable characters.

@chrisl When using your code the output alsways results in FFFFFFF0FFFFFFF0

@Juraj I did not try the 1.* versions but PlatformIO in VSCode instead.

Mhh, then this seems to be a problem with what is send by the Arduino IDE 2.0 through serial (it should not send all high bytes with normal text). Since it is still beta, it might be a bug.

Check the baud rate and associated parameters (115200,N,8,1).