text:
Input vs input_pullup
I'm a beginner in Arduino and can't understand some things. How does input pin in Arduino work? I want to set one of the pins as input. When should I use input and when input_pullup? What are the differences between them?

Input pin working-
An input pin on an arduino board uses something called   Tristate buffer to expect a voltage at the pin.
Input pullup-
When a pin is configured just as an input (without a definite voltage connected to it), the pin will return random values based on the electrical interference present around it, for example the neighbouring pin.
So to solve this issue, input pullups are used. Essentially it sets the default state of the pin to HIGH or 1, so that the pin is not affected by interference.
You can experience this yourself using the following program, with a pushbutton from Ground to pin 7, and the Serial monitor-
No pullup-
void setup(){
// Dont have to put any pin definitions here as by default it input
// This code will return random values until the button is pressed
Serial.begin(9600);
}

void loop(){
Serial.println(digitalRead(7));
}

Now for the one with Pullup-
void setup(){
pinMode(7, INPUT_PULLUP);
Serial.begin(9600);
// This code will return 1/HIGH until the button is pressed
}

void loop(){
Serial.println(digitalRead(7));
}

Random info- There's input pulldown on some boards, guess what that does?

The pin inputs are sensitive enough to nearby electrical noise that if the pin is floating - not positively pulled up to the supply voltage, or down to ground - the input will read randomly HIGH or LOW. A pullup resistor of 10K Ohms or so connected between the pin and the supply voltage is strong enough to overcome the noise, but is itself easily overcome by a signal applied to at the pin input:

simulate this circuit – Schematic created using CircuitLab
This means that when the pin is not connected, it will have stable HIGH reading.
While you can put the pullup on your circuit board, as in the schematic above, Arduinos have a built-in pullup resistor that can be connected to the pin simply by selecting 'INPUT_PULLUP' in your code, and it does exactly the same thing. It is a convenient way to save space and a component on your circuit board or make it slightly quicker to wire your breadboard. And in the case of a breadboard in particular, the plug-wires are excellent antennas for picking up noise, while the built-in pullup resistor is within the chip, close the pin-receiver, and it makes the circuit dramatically more stable.


text:
DHT11 humidity and temperature sensor
Hello. I've got a question about DHT11 sensor. Why should pullup resistor be connected as on the image below:

while as far as I know, pullup resistor should be placed between Arduino 5V pin and Vcc of sensor as shown here:

PS: I know that there is a wrong icon of DHT11, but I couldn't find a correct one.

I don't know why but the datasheet says dataline must be connected to 4.7K pullup
http://robocraft.ru/files/datasheet/DHT11.pdf

Then it wouldn't be a pull-up resistor; Vcc already is 5V. Signals are what need to be pulled high or kow.

@Dave Newton but it seems to me, that when the resistor is connected as shown in the first image, it's in parallel to Vcc-OUT in sensor therefore resistance between 5V and OUT is 0.

If you draw a proper schematic, you will see that, in the first drawing, the resistor is between Vcc and Out (also called “data”). It “pulls up” the data/Out pin to a high logic level when there’s no internal or external signal driving it.

You require a pullup resistor between the data wire and VCC because the DHT11 uses a bidirectional communication system on a single wire.  When neither end is communicating both ends of the link will be in "high impedance" mode - i.e., input mode. In that case the signal will be "floating" and needs the pullup to keep it in a known state.
When actively communicating the outputs switch to "open drain" mode to allow then to pull the signal low against the pull of the pullup resistor.
A resistor in series with the Arduino's 5V and the VCC of the DHT11 is not a pullup resistor. It is not an arrangement that you would ever want, since it would make the voltage to the DHT11 unstable.

Note that the pullup is typically not required when using one of the common breakout boards for DHT11 (from Adafruit or similar), because they already include it.

source: Stack Exchange

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

sort: votes


text:
Writing multiple inputs to serial port using a while loop
I am trying to get the serial monitor to prompt me to input two settings - the PWM level and the Resonance level. I am being prompted to input the PWM level, but before I can input the Resonance level it is set to zero and then I am asked again for the PWM level.
I am using Serial.flush(); inbetween the commands to clear the serial input, but I still cannot input the Resonance level before it is set to zero.
Here is my code:
int PWMPin = 10;       // Pin 10 connects to MOSFET gate on breadboard
int ResPin = 4;        // Pin for the resonator stage

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);   // Define baud rate for console to be 9600
  pinMode(PWMPin, OUTPUT);
  pinMode(ResPin, OUTPUT);

}

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

Serial.println("What PWM level do you want to test?");   // Testing only
 while (Serial.available() == 0) {
     // Wait for user input
  }
  int test_level_PWM = Serial.parseInt();
    analogWrite(PWMPin, test_level_PWM);
    Serial.print("PWM Level: ");
    Serial.println(test_level_PWM);

Serial.flush();

Serial.println("What Resonance level do you want to test?");
 while (Serial.available() == 0) {
     // Wait for user input
  }
  int test_level = Serial.parseInt();
    analogWrite(ResPin, test_level);
    Serial.print("Resonance Level: ");
    Serial.println(test_level);

   delay(1000);

Here is the serial monitor output. I was able to input the PWM level but the Resonance level was set to zero immediately after and then I was asked to input the PWM level again.

I would consider restructuring this into a state machine with (something like) "input" and "run" states. I'd also reconsider using parseInt because its default timeout of 1s can lead to unexpected behavior; might just want to handle that manually.

Serial.flush() doesn't do what you think. the line end characters will be still in the RX buffer. flush() waits for TX buffer to be send. https://www.arduino.cc/reference/en/language/functions/communication/serial/flush/

in the serial monitor, in place of new line ending, select no line ending. After making this change, your code worked on my system.

Your line
   Serial.flush();
is probably intended to remove additional input after the expected numerical input. But that's not what it's doing. (See @jurai's comment)
Either avoid additional input like NewLine characters, or remove them using something like
while (Serial.available()) {delay(1); Serial.read();}
( The delay(1); takes care of slowly coming in serial data at 9600 Baud )

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


text:
Connect two 64x32 RGB P4 panels Arduino Mega
I'm using an Arduino Mega and two RGB Led Panels to plot some data. The problem is that the data plotted in the first panel is duplicated in the second as well. What I want is to plot the data on both using just one Arduino Mega. Is it possible? I've read that you can achieve it using one Mega for each panel or using a more powerful controller for both. This question was asked before here
Join two rgb ledPanel 32x64 in order to get one 64x64 (How to)
but no clear answer about commands or changes to made in the code were given. Any idea?
Thanks in advance

I'm not sure how to handle this, because you're basically describing your own question as a duplicate.  So, it seems like anyone attempting to answer it shouldn't answer on the existing question.  If you're around here long enough, not very long, to get a few reputation points you'd be able to set a bounty on the existing question.

I voted up and made some minor edits to the linked question. There's a small chance it may receive some attention being further up the list. I also looked in the RGB Matrix library they reference and about the only I have to say about it thus far is a warning, that it will allocate 32643, over 6 KByte for one matrix.  Since the Mega 2560 has 8Kbyte, it doesn't appear that trying to make two instances of it will fly.


text:
I need a good battery reccomendation
I have simple project composed of an Arduino Nano, a HC-05 module, and a small toy DC motor controlled using a L293D driver, I want to be able to power this circuit entirely using a battery, here is what I tried:
-The motor/L293D combo works when the Arduino Nano is powered through it's USB jack, except the L293D is drawing power from the Nano, which I know is very bad practice, but I only did it for testing purposes.
-The HC-05 module also works fine when the Nano is powered through it's USB jack, as expected.
-However, the power received through the USB jack is not enough power for both the HC-05 and the L293D & motor simultaneously, if I want to change the PWM through the HC-05, I have to disconnect the motor, send the instruction, then disconnect the HC-05 and re-connect the motor.
-I have tried 3, pretty much new 9V batteries, none of them were enough to power anything, not the Nano board through the Vin pin, not an Uno board through barrel plug, not the motor, nothing, except a LED diode, I've read somewhere that most brands of these kinds of batteries don't actually provide nearly as much power as they claim, so that might explain it. (In case it's relevant, the brands I tried are VARTA, Uniross and Goldmen.)
-Someone gave me the idea of using an old mouse cable to power the Arduino, by taking the VCC and GND wires from the mouse cable and using those to power the Nano board through it's Vin and GND ports, it works, but not any components connected to it, not even the HC-05 module, which I even tried powering directly from the mouse cable, which lit up it's LED, but did not get it to work.
Honestly this isn't that relevant, I just wanted to make sure the Vin pin worked.
-Also, few side notes:
My multimeter mysteriously stopped working when I actually needed it, which is why I couldn't take any measurements.
The L293D datasheet and other pinouts suggest no less than 12V supply voltage, so maybe a 9V battery wasn't the right answer to begin with.
The power coming from the mouse cable is enough to power the DC motor independently, but not through the L293D, it says online the average output for these cables is around 5V, but without measurements I can't be sure.
The battery holder for the toy train that has DC motor inside accepts 1.5V batteries wired in series, and considering there's not much else there aside from the motor itself, it's safe to say that 3V is the minimum required voltage for the motor.
So, what battery do you think would be most suitable for my project?
And if it's not against the rules, what brand would you recommend?

9V batteries aren't any use for anything at all. You need the voltage of the motor plus the voltage drop of the motor driver. For 3V motors the L293D is useless. TBH I wouldn't recommend using it for anything. It's old technology. You want a MOSFET based motor driver.

@Majenko Well, you see, I'm trying to keep the circuit a small as possible, because I'm installing the whole thing on a small 3x13x3cm toy train, the one with the motor I'm trying to control, so I'm either gonna have to stick to the l293d, or something as equally small, something that fits on a 4.5x3 breadboard while also leaving enough space for the HC-05 module, got anything that fits that description?

The L293D has about a 2.6V drop on the output pins. That means for a 3V motor you need to provide about 5.6v for it to run at full speed. 5V will work, but it will run slightly slow and underpowered.
9V batteries are useless. Only any good for very low power applications like smoke alarms. They just can't provide the current you need.
Instead you need to be looking at model aircraft / drone suppliers for a "2S" battery (7.4V Li Poly / Li Ion) and a suitable 5V (or 5.6V if you can get it) UBEC (switching regulator).

Is the UBEC necessary? Also will 7.4V be enough, L293D data sheets and pinouts always specify 12V as minimum voltage.

The datasheet I just looked at specified 4.5v to 36v for the supply voltage. I don't know what datasheet you've been reading.  If you have too high a voltage you can burn out our motor.

Yeah I checked more reliable resources and you're right, so what about the UBEC? Is it a necessity or will one of the batteries you mentioned be sufficient on it's own?

That depends entirely on your motor.

Is there a way for me to know? We already established my motor requires around 3V, if I'm supplying somewhere between 5 to 7.4V, I don't think there's any risk of burning the motor, that's similar to what the Nano board is supplying so I don't think there's any risk...Which does remind me, what about the Nano board itself as well, the battery I need will be supplying the Nano board as well, so I'm assuming I'm gonna need a battery that supplies double of what we discussed, right?

7.4V is fine for the VIN to the nano. If you think you need to double it then you need to put the electronics away in a drawer and go and learn some basic theory before you start.

No need to be condescending, I studied electronics for 6 years between highschool, college and a training center, but there's a big difference between studying something and actually learning it, evidenced by the fact that I learned nothing, which is why I'm now taking a more practical approach by attempting these kinds of projects, thank you.

Then you should know that devices connected in parallel (as you would for this) sum the current, not the voltage.

Yeah I guess, they taught us Kirchhoff's law, but it's practical application, merely another formula to be regurgitated in exams.

You should spend some time doing a little revision before you blow something up then...

I meant to say "but not it's practical application", but yeah you're right, I'm on a tight schedule with this project, but I'll take a more methodical approach next time, thank you.

You could also use a 4 channel relay for making the motors work and they can be independent of using power from arduino and is really effective, I sometimes use it for high voltage optocoupling and can be used for small ones too all you need to do is build logic and everything would work fine I assume you know how to reverse polarity on a dc motor.
Relays are not power hungry and can be powered from arduino but if you could give it an external 5 volts that would be better.
Which in case of L293d driver is not the case you would require at least 12 volt to power the driver itself.

Well, you see, I'm trying to keep the circuit a small as possible, because I'm installing the whole thing on a small 3x13x3cm toy train, the one with the motor I'm trying to control, so I'm either gonna have to stick to the l293d, or something as equally small, something that fits on a 4.5x3cm breadboard while also leaving enough space for the HC-05 module, got anything that fits that description? Plus I still need to find a decent power source so if you have a recommendation for that as well I wouldn't mind.


text:
Set Value for a characteristic fails using BLE ESP32
I'm working on a project that uses a Raspberry pi to trigger a microcontroller to read data from an accelerometer for some amount time then have that data available for the RPi to read it over BLE. I Have been able to set up my ESP32 Thing plus as a server and used both a RPi and the BLE scanner app to send it a message a start it to record data. I am struggling to get this data to be set at the characteristic value so that my RPi can then read it.
My aim is to convert that data from an accelerometer that is stored in an array to a string which can then be read by the RPi.
I have tried to just set the value in my code with some string and the actually value I want to send but both of them fail and cause the controller to reboot.
Is it something to do with the way I am setting up the data or is the code structure fundamentally wrong? please see code below.
#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEServer.h>

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

#define SERVICE1_UUID        "4fafc201-1fb5-459e-8fcc-c5c9c331914b"
#define CHARACTERISTIC1_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a8"

#define CHARACTERISTIC2_UUID "279766d1-630f-4db9-9b84-81731a59d46b"

#define CHARACTERISTIC3_UUID "837c3fbd-77e6-43ad-9921-c3526139a7dc"

BLECharacteristic *pCharacteristic1;
BLECharacteristic *pCharacteristic2;
BLECharacteristic *pCharacteristic3;

//Accelerometer Variable
const int xpin = A2;                  // x-axis of the accelerometer
const int ypin = A4;                  // y-axis
const int zpin = A3;                  // z-axis (only on 3-axis models)
int LoopCounter = 0;
const int ArraySize = 250;
int XValueArray[ArraySize];
int YValueArray[ArraySize];
int ZValueArray[ArraySize];
int AValueArray[ArraySize];
char XValueString[500] = "";
char YValueString[500] = "";
char ZValueString[500] = "";
bool MeasurmentTaking = false;
bool ValidMessage = false;
int XValue = 0;
int YValue = 0;
int ZValue = 0;
//Millis variables
unsigned long PreviousMillis = 0;
unsigned long CurrentMillis = 0;
const int PeriodRead = 4;
const int NumberOfPoints = 250;

//Class to read incomming messages
class MyCallbacks: public BLECharacteristicCallbacks {

    void onWrite(BLECharacteristic *pCharacteristic1) {
      std::string RecievedValue = pCharacteristic1->getValue();

      if (RecievedValue == "Start") {
        MeasurmentTaking = true;
        ValidMessage = true;
      }//If
      else{
        }//Else
    }
};

void setup() {
  Serial.begin(115200);
  //Set up accelerometer pins
  pinMode(xpin, INPUT);
  pinMode(ypin, INPUT);
  pinMode(zpin, INPUT);

  //Set up BLe device
  BLEDevice::init("MyESP32");

  BLEServer *pServer = BLEDevice::createServer();
  BLEService *pService = pServer->createService(SERVICE1_UUID);               //XAxis accellerometer
  BLECharacteristic *pCharacteristic1 = pService->createCharacteristic(
                                         CHARACTERISTIC1_UUID,
                                         BLECharacteristic::PROPERTY_READ   |
                                         BLECharacteristic::PROPERTY_WRITE  |
                                         BLECharacteristic::PROPERTY_NOTIFY
                                       );

  BLECharacteristic *pCharacteristic2 = pService->createCharacteristic(       //YAxis accellerometer
                                         CHARACTERISTIC2_UUID,
                                         BLECharacteristic::PROPERTY_READ   |
                                         BLECharacteristic::PROPERTY_WRITE  |
                                         BLECharacteristic::PROPERTY_NOTIFY
                                       );

  BLECharacteristic *pCharacteristic3 = pService->createCharacteristic(       //ZAxis accellerometer
                                         CHARACTERISTIC3_UUID,
                                         BLECharacteristic::PROPERTY_READ   |
                                         BLECharacteristic::PROPERTY_WRITE  |
                                         BLECharacteristic::PROPERTY_NOTIFY
                                       );

  pCharacteristic1->setCallbacks(new MyCallbacks());

  pCharacteristic1->setValue("X");
  pCharacteristic2->setValue("Y");
  pCharacteristic3->setValue("Z");
  pService->start();

  BLEAdvertising *pAdvertising = BLEDevice::getAdvertising();
  pAdvertising->addServiceUUID(SERVICE1_UUID);
  pAdvertising->setScanResponse(true);
  pAdvertising->setMinPreferred(0x06);  // functions that help with iPhone connections issue
  pAdvertising->setMinPreferred(0x12);
  BLEDevice::startAdvertising();
}

void loop() {
  Serial.print(MeasurmentTaking);
  Serial.println(ValidMessage);

  //Record Data from accelerometer to array
  if (ValidMessage == true){
    MeasurmentTaking = true;
    while (MeasurmentTaking == true){
          CurrentMillis = millis();
          if (LoopCounter == NumberOfPoints){
            MeasurmentTaking = false;
            LoopCounter = 0;
            }//If
          else if(CurrentMillis - PreviousMillis >= PeriodRead){
            int XValue = analogRead(xpin);
            Serial.println(XValue);
            XValueArray[LoopCounter] = XValue;

            int YValue = analogRead(ypin);
            Serial.println(YValue);
            YValueArray[LoopCounter] = YValue;

            int ZValue = analogRead(zpin);
            Serial.println(ZValue);
            ZValueArray[LoopCounter] = ZValue;

            AValueArray[LoopCounter] = ZValue;
            PreviousMillis = CurrentMillis;
            LoopCounter = LoopCounter + 1;
            }//Else If

          }//While

    //Convert array values to string
    Serial.print("XValueArray");
    for (int i = 0; i <= ArraySize; i++){
      Serial.println(XValueArray[i]);
      int buff1 = XValueArray[i];
      char str1 [7];
      sprintf(str1,"%u" ,buff1);
      strcat(XValueString,str1);
      strcat(XValueString, ",");
      }//For
    Serial.println();
    Serial.print("YValueArray");
    for (int j = 0; j <= ArraySize; j++){
      Serial.println(YValueArray[j]);
      int buff2 = YValueArray[j];
      char str2 [7];
      sprintf(str2,"%u" ,buff2);
      strcat(YValueString,str2);
      strcat(YValueString, ",");
      }//For
    Serial.println();
    Serial.print("ZValueArray");
    for (int k = 0; k <= ArraySize; k++){
      Serial.println(ZValueArray[k]);
      int buff3 = ZValueArray[k];
      char str3 [7];
      sprintf(str3,"%u" ,buff3);
      strcat(ZValueString,str3);
      strcat(ZValueString, ",");
        }//For
    Serial.println();
    Serial.print("XvalueString");
    Serial.println(XValueString);
    Serial.print("YvalueString");
    Serial.println(YValueString);
    Serial.print("ZvalueString");
    Serial.println(ZValueString);
    MeasurmentTaking = false;

    //Set values as new data
    pCharacteristic1->setValue("Test X");
    pCharacteristic2->setValue("Test Y");
    pCharacteristic3->setValue("Test Z");
    ValidMessage = false;
  }
  else{
    }

  delay(1000);
}

Example of the string I would like to send.
<1967,1967,1989,2000,2000,2000,2003,1997,1984,1980,1999,1999,2000,2000,2021,2000,1969,1973,1999,2000,1999,1995,1995,1986,1978,1998,1991,2000,2002,1999,2000,1968,1989,1995,2000,2000,2000,2001,1983,1979,1993,2000,1997,2002,2000,1999,1967,1986,1988,1999,2000,2001,2000,1983,1971,2059,1999,2000,2000,1997,2000,1963,1989,1997,2000,1999,2015,2003,1984,1979,1986,2003,2000,1997,2001,2001,1968,1984,1991,1998,1997,1998,2000,1981,1979,2000,2000,2002,2002,1999,2000,1968,2016,1997,2000,2000,2000,2001,1981,1982,1991,2000,2000,2001,2000,2000,1967,1987,1998,2005,2001,2000,2001,1984,1980,2000,2000,2000,2000,2001,1998,1967,1994,2000,2000,2000,2000,1997,1985,1981,1996,2000,2000,2000,2000,2000,1971,1989,1999,2001,2001,2000,2000,1984,1970,1999,2001,2000,2000,1999,2000,1968,1987,2000,1990,2000,2001,1997,1985,1980,1995,2000,2000,1999,2000,2000,1968,1989,1997,2000,2000,2002,2006,1984,1979,1994,1998,1998,2000,2000,2000,1968,1990,1997,2000,1999,1998,2000,1983,1980,1998,2000,1997,1999,1998,2002,1963,1985,2000,2000,1999,2002,1999,1983,1971,1995,1989,1985,2000,1999,2000,1966,1989,2001,2000,2000,1983,2000,1982,1978,1997,2000,2000,2001,2003,1999,1967,1989,1997,1999,2000,2002,1999,1997,1979,1997,1999,1999,1999,1999,2000,1968,1990,1999,1999,2002,2000,2000,1983,1978,1859>

Thank you for any help or guidance to an answer.


text:
What is required to run a program preciously uploaded and working from Arduino IDE via PC... (Nano 33 IoT)... but now powered via VIN, not USB?
The Arduino IDE works beautifully with the Nano 33 IoT using the IDE and is powered via USB. I now want to disconnect the USB and power thru the VIN pin (6-22V). The green led comes on but the program is not there or not running. Please help.  thank you!

Does this answer your question? MKR GSM 1400 Works only when connected to computer

Once you upload your code into the Arduino, it is there, burned into the flash memory of the microcontroller and it runs no matter how you power your board.
However, if in order to run your program is dependent on the Serial interface, for instance you added a line like while(!Serial) and you have not connected the USB cable, the program will loop at that point and will not continue.
For more information please upload your code.

you made the same error as OP. you didn't search for an existing answer


text:
Global Variable not updating…
I'm building a small project to maintain a copper plating tank's temperature and filter pump duty cycle. I'm using the Adafruit Feather platform to hold an 8 segment matrix coupled with a Teensy 3.2 (on a Feather shield) to calculate and display temp. There is a 10K Pot on A0 and an 8 segment NeoPixel Strip to set and display pump duty cycle from 1 to 8 corresponding to .125*hour and 100% on. There is also a push and hold set switch to operate temperature target point setting using the same pot.
Things that work: Almost Everything!
Thing that doesn't work:
Changing the Duty Cycle knob (which changes the duty cycle global variable) after turning the unit on doesn't seem to change the on/off times other than to successfully change the NeoPixel display. If the unit is turned on at a particular duty cycle, the program will run that duty cycle successfully. While running, if I change the duty Cycle to 8, I don't get a "100% On". In other words the change in the duty cycle variable doesn't seem to change the on time and off time variables in the code while running.
Q: What do I need to do to make the duty cycle setting work on the fly?
Oh... That Volatile Float declaration was my last desperate attempt, Please ignore / forgive. ;-)
Hopefully the fix is as simple as the code. ;-) I just don't see it and my (perhaps flawed) understanding of global variables is hit a wall.
Any help will be much appreciated. Thanks.
Jeff
Code:

/***************************************************
  Copper Plating Tank Control - v1.1
  by Jeff W. Parisse - July 7st, 2021
  www.coppercholla.com

  This program runs a programmable interval timer for chemical pump
  duty cycle and a programmable temperature setting and heating control
  for maintaining plating solution temperature.

  Processor: PJRC Teensy 3.2
  Additional Libraries: Adafruit Industries LLC
  Temperature Sensor: Adafruit MAX31865 w/P1000 Platinum Wire Probe
  Pin Outs:
    Setting Knob: Pin A0
    Matrix Display: Feather Matrix I2C 0x70
    Neopixels: Pin 5
    MAX31865: CLK Blue
    MAX31865: SDO Yellow
    MAX31865: SDI White
    MAX31865: CS Pin 6 Green
    Temp Set Switch: Pin 8
    Chemical Pump: Pin 9
    Tank Heater: Pin 10

 ****************************************************/

#include <Adafruit_MAX31865.h>
#include <Adafruit_GFX.h>
#include "Adafruit_LEDBackpack.h"
#include <Adafruit_NeoPixel.h>

#define knobPin A0
#define ledPin 5
#define csPin 6
#define switchPin 8
#define pumpPin 9
#define heaterPin 10
#define ledCount 8
#define sampleNum 4
#define RREF      4296.0
#define RNOMINAL  1000.0

Adafruit_MAX31865 thermo = Adafruit_MAX31865(csPin);
Adafruit_7segment matrix = Adafruit_7segment();
Adafruit_NeoPixel strip(ledCount, ledPin, NEO_GRB + NEO_KHZ800);

float targetTemp = 77.0;                // Starting Value
float readTemp = 0;
float toleranceTemp = 0.25;
float tempSum = 0;
float cTemp = 0;
float fTemp = 0;
volatile float dutyCycle = 4;
unsigned long previousTime = 0;
unsigned long oneHour = 3600000;       // 1 Hour in Milliseconds
unsigned long timeOn = 450000;         // 7.5 Minutes in Milliseconds
unsigned long pumpInterval = timeOn;
boolean pumpState = true;

void setup() {
  thermo.begin(MAX31865_3WIRE);;
  matrix.begin(0x70);
  strip.begin();
  strip.show();
  pinMode(csPin, OUTPUT);
  pinMode(heaterPin, OUTPUT);
  pinMode(pumpPin, OUTPUT);
  pinMode(switchPin, INPUT_PULLUP);
  digitalWrite(csPin, LOW);
  digitalWrite(heaterPin, LOW);
  digitalWrite(pumpPin, LOW);
}

void loop() {
  // Read Set Switch
  int setSwitch = (digitalRead(switchPin));
  while (setSwitch == LOW) {
    int readKnob = analogRead(knobPin);
    targetTemp = map(readKnob, 1, 1023, 67, 87);
    matrix.print(targetTemp, 1);
    matrix.writeDisplay();
    setSwitch = (digitalRead(switchPin));
  }

  // Read, Convert, and Display Temp
  tempSum = 0;
  for (int i = 1; i <= sampleNum; i++) {
    readTemp = thermo.temperature(RNOMINAL, RREF);
    tempSum = tempSum + readTemp;
  }
  cTemp = tempSum / sampleNum;
  fTemp = (cTemp * 1.8) + 32;
  matrix.print(fTemp, 1);
  matrix.writeDisplay();

  // Heater Logic
  if (fTemp < targetTemp - toleranceTemp) {
    digitalWrite(heaterPin, HIGH);
  }
  else if (fTemp > targetTemp + toleranceTemp) {
    digitalWrite(heaterPin, LOW);
  }

  // Read and Display Duty Cycle
  int readKnob = analogRead(knobPin);
  dutyCycle = map(readKnob, 1, 1023, 1, 8);
  for (int i = 0; i <= ledCount; i++) {
    strip.setPixelColor(i, 0, 0, 0);
  }
  strip.show();
  for (int i = 0; i <= dutyCycle - 1; i++) {
    strip.setPixelColor(i, 0, 0, 20);
  }
  strip.show();

  // Pump Timer
  digitalWrite(pumpPin, pumpState);
  unsigned long timeOn = ((dutyCycle / 8UL) * oneHour);
  unsigned long timeOff = (oneHour - timeOn);
  unsigned long currentTime = millis();
  if (currentTime - previousTime >= pumpInterval) {
    if (pumpState) {
      pumpInterval = timeOff;
    }
    else {
      pumpInterval = timeOn;
    }
    pumpState = !(pumpState);
    previousTime = currentTime;
  }
}

Had you tried to print and test to output of map function?

And why is it a float if its value can only be an integer from 1-8?

I do not really understand what may be the cause of your problem, but I
have identified two issues that could potentially be related.
You have:

dutyCycle = map(readKnob, 1, 1023, 1, 8);

Because of some rounding issues in the Arduino map() function, this
may not work as you expect: the output will be 8 only if the input
reaches 1023. If readKnob is 1022, dutyCycle will be 7. This may
explain why you never see the pump being constantly on.
The way map() works makes most sense if you think in terms of
half-open intervals, open on the right. If you write:
dutyCycle = map(readKnob, 0, 1024, 1, 9);

you will get a perfect mapping from [0, 1024) to [1, 9). Perfect in the
sense that there will be exactly 128 input values mapped to each output
value:
[  0, 128) → 1
[128, 256) → 2
[256, 384) → 3
...

And later:

for (int i = 0; i <= ledCount; i++) {
    strip.setPixelColor(i, 0, 0, 0);
}

The strip has ledCount pixels, numbered 0 to ledCount-1. This loop
will set the color of pixels 0 through ledCount inclusive. The last
iteration goes beyond the end of the strip, and it is most likely
corrupting memory, i.e. overwriting whatever data happens to sit right
after the memory area used for the strip. If this is overwriting some
variable related to the duty cycle, that may explain the weird behavior
you experience.

Thanks Edgar… I will rewrite this after lunch and feedback…

Fabian… at first I did when I was getting the led routing working. Then I stopped monitoring that function… probably why I may have missed it.

Dave, because I was grasping at straws rather doing what I doing now, asking for help, which is way more rational… I’ll fix that code asap. :-)


text:
Connecting Arduino Uno's TX pin directly to Esp8266 esp-01
I am new to esp8266 esp-01 and trying to figure out how to use it, in many tutorials on internet, I have seen people have connected Arduino uno's TX pin directly to esp8266 esp-01 without any voltage divider, we know that Arduino TX pin uses 5v, so isn't that will kill the esp-01 which is not 5v tolerant ?

There is still no definitive answer to this from Espressif. Anecdotal evidence says that the ESP8266 is 5V tolerant. The (current) datasheet does not say if it is or not. An early version may have said that it is. No one really knows.

https://hackaday.com/2016/07/28/ask-hackaday-is-the-esp8266-5v-tolerant/

Do it the correct way, use a logic level converter, they are inexpensive and you generally have less connections by the time everything is finished..

Esp01 is not 5v tolerant so it could corrupt it at any time so don't do this and use voltage divider.


text:
Arduino Uno Esp8266 AT commands
I am trying to send AT commands to esp-01 through serial monitor I have uploaded a blank sketch to Arduino , whatever command I send to ESP I get reply ERROR.
After reconnecting esp-01 I got some garbage vales then ready.
Can anyone help me what I am doing wrong.
This is what I got on serial monitor

These are the connections I am using, I tried to use voltage divider but after using voltage divider, Esp's blue led turned on and nothing happened so I used just used the resistors in series between TX and TX of both devices

This is the voltage divider circuit I was using(that didn't worked)

Please upload your code so it can be examined against the results you are getting.

did you set line ends in Serial Monitor to "Both"?

you want a voltage divider on receiver pin of esp8266. the RX pin of the board is TX pin of the USB chip (because the USB chip is connected to ATmega RX to TX)

The hardware serial, pins 1 and 2, are used by the Arduino to communicate to the USB adapter to your computer.  When you connect another device to them, it interferes with the communication between your computer and the Arduino.
The solution is to connect the ESP-01 to another set of pins and use the SoftwareSerial library to create a second serial port for it.  The code then needs to listen on both serial ports and move data between them.
Also, you need to use the voltage divider or you risk burning out the input pin.  To make the voltage divider, connect the Arduino output to the top of the divider and the ESP-01 to the middle.  You appear to have those reversed in your schematic.

here the USB chip of Uno is connected to the esp8266 and the ATmega is inactive

The paragraph about the voltage divider regarding Rx is relevant though:To make the voltage divider, connect the Arduino RX0 to the top of the divider and the ESP-01 RXD to the middle. You appear to have those reversed in your schematic.

Sometime when I connect CH-PD to 3.3v, SP flash IC starts getting hotter and nothing works can you tell me what causing that ?


text:
Accelerometer value meaning
I'm currently using the MPU-6050 accelerometer to receive the acceleration and angular velocity data. I'm trying to process the data for my experiment but I can't understand the exact meaning of it. I have threee questions about the situation. I append the arduino code below.
First, I happen to know that the AcX value of the code below means how much the sensor is inclined along the x axis. Is there other way to get acceleration directly? or Do I have to use formula(v = v_0 + a*t)?
Second, for the gyro sensor, I can't understand the meaning of the value. Does it sends the angular velocity or angular acceleration and if it is one of these, what's the limit?
Third, according to code, it receives data in the form of 2^14(14bit) but sometimes it sends value way over the limit. How can I translate raw data to rather regular unit like degree and rad?
Thank you
const int MPU_addr=0x68;  // I2C address of the MPU-6050
int16_t AcX,AcY,AcZ,GyX,GyY,GyZ;

void setup(){
  Wire.begin();
  Wire.beginTransmission(MPU_addr);
  Wire.write(0x6B);  // PWR_MGMT_1 register
  Wire.write(0);     // set to zero (wakes up the MPU-6050)
  Wire.endTransmission(true);
  Serial.begin(9600);
  Serial.println("CLEARDATA");
  Serial.println("LABEL,TIME,AcX,AcY,AcZ,GyX,GyY,GyZ");
}

void loop(){
  Wire.beginTransmission(MPU_addr);
  Wire.write(0x3B);  // starting with register 0x3B (ACCEL_XOUT_H)
  Wire.endTransmission(false);
  Wire.requestFrom(MPU_addr,14,true);  // request a total of 14 registers

  // deviding the 16bit input??
  AcX=Wire.read()<<8|Wire.read();  // 0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L)
  AcY=Wire.read()<<8|Wire.read();  // 0x3D (ACCEL_YOUT_H) & 0x3E (ACCEL_YOUT_L)
  AcZ=Wire.read()<<8|Wire.read();  // 0x3F (ACCEL_ZOUT_H) & 0x40 (ACCEL_ZOUT_L)
  GyX=Wire.read()<<8|Wire.read();  // 0x43 (GYRO_XOUT_H) & 0x44 (GYRO_XOUT_L)
  GyY=Wire.read()<<8|Wire.read();  // 0x45 (GYRO_YOUT_H) & 0x46 (GYRO_YOUT_L)
  GyZ=Wire.read()<<8|Wire.read();  // 0x47 (GYRO_ZOUT_H) & 0x48 (GYRO_ZOUT_L)

  //Serial.print("AcX = ");
  Serial.print(AcX);
  Serial.println(",");
  //Serial.print(",");
  //Serial.print(" | AcY = ");
  //Serial.print(AcY); Serial.print(",");
  //Serial.print(" | AcZ = ");
  //Serial.print(AcZ); Serial.print(",");
  //Serial.print(" | GyX = ");
  //Serial.println(GyX);
  //Serial.print(" | GyY = ");
  Serial.println(GyY); //Serial.print(",");
  //Serial.print(" | GyZ = ");
  //Serial.println(GyZ);
  delay(200);
}

Doesn't the datasheet answer these questions?

Is there other way to get acceleration directly? or Do I have to use
formula(v = v_0 + a*t)?

The code appears to be currently retrieving the raw X, Y & Z acceleration and storing it in AcX, AcY & AcZ.  The equation "v = v_0 + a*t" appears to be deriving velocity.  So the question is confusing.

...for the gyro sensor, I can't understand the meaning of the value. Does
it sends the angular velocity or angular acceleration

The accelerometer sensors measure acceleration.  As the last question ultimately asked for angles, the gyroscope is not needed.  However, on page 12 in the MPU-6050 specifications the dimensions of the gyroscope is given in degrees per second or angular velocity.  Likely the mechanism within the chip depends on the Coriolis effect

...and if it is one of these, what's the limit?

On the same page the MPU-6050 chip specification shows a table containing values such as GYROSCOPE SENSITIVITY & Full-Scale Range.  Consider reading these and other values regarding the gyroscope.

...according to code, it receives data in the form of 2^14(14bit) but
sometimes it sends value way over the limit.

The code retrieves a high 8 bit and low 8 bit value for each axis of the accelerometer and the gyroscope.  This makes a 16 bit value.  Not a 14 bit value.

How can I translate raw data to rather regular unit like degree and
rad?

To obtain an angle in degrees only the accelerometer is required.
Consider calibrating the accelerator for offset and magnitude errors before using the raw values.
Consider constraining the problem such that the accelerometer is only rotated around the Z-axis.
The angle can be found by taking the inverse tangent of the ratio of the calibrated X acceleration and calibrated Y acceleration.

Other considerations:

If angles are desired in 3 dimensional space consider using commonly referred to values such as pitch, roll & yaw.  In which case many situate the accelerometer such to use these equations:

The above equations, a discussion and some example code can be found here.

So far, all the equations discussed use trigonometry and can go to infinity (unusable results) given certain inputs.  The mathematical equivalent of gimbal lock if you will.  To avoid this consider using quaternions.  This mathematical method of representing rotation in 3 dimensional space does not suffer the above problem, is easier for computers to calculate and is used extensively in computer graphics.

Re “All the sensors measure acceleration”: gyroscopes measures angular velocity, not angular acceleration. The unit used in the datasheet for gyro data is degrees per second.

That's interesting.  I can't imagine how mechanically such a device is made.  If you and I are both correct, then the MPU-6050 must be doing some type of integration to get velocity (i.e. to get a constant value for a MPU-6050 gyroscope situated at the center of an operating 33 & 1/3 RPM phonograph record player).

Ah, never mind, I see how it's done: Coriolis effect.  Learn something new everyday.

FYI, for anyone reading this, looking at the answer and scratching their head ... I changed the answer to match what @EdgarBonet was commenting on.  Thank Edgar!

"currently retrieving the raw X, Y & Z acceleration" While processing data with python code below, I happen to know that it's the location data. Can you explain what's going on?

So, the sensor gets the acceleration(may be loaction) and angular velocity data(maximum 2000 dps -according to the specification) in the form of 16bit(+,-). And for the translation, I may have to regard other values or formula. Am I right?

@JohnCho, the integral of acceleration gives velocity and the integral of velocity gives location. Consider opening a separate stack exchange question with your Arduino code regarding this or switch to another stack exchange site like Physics or Math with a more general question about acceleration, velocity and position.

@st2000, I was just curious about the data which seems to send location even though it has the name of AcX. By the way, Thanks!

Curiosity is a good thing!  I have only worked with a couple of IMUs.  But have found they report acceleration (and, of course, angular velocity).  Keep in mind deriving position from acceleration is very difficult. Deriving position is not ordinarily done with only acceleration data.  The difficulty comes when dealing with the accumulated errors. The only exception I am aware of is gaming.  Here, since you are in a virtual world, ending up half way across the living room, as long as you don't hit anything, isn't that big of a deal.

Ok, I've misunderstood the acceleration sensor. Thanks!


text:
pull-up or pull-down
Do you have to build the circuit on an external board every time you decide there is a need
for a pull-up or pull-down circuit? If not, then what is the alternative and how can you use
it?

This depends on what you are doing.
The IO hardware of the Uno (more specific the Atmega328p, which is the used chip) has internal pullup resistors, that can be used, when the pin is configured as input. This can be done in one line:
pinMode(pin_number, INPUT_PULLUP);

This is true for all AVR based chips.
Other, more complex and capable chips also have an internal pulldown resistor (as I remember this is true for the ESP32 for example). In this case you can do
pinMode(pin_number, INPUT_PULLDOWN);

If you are using special hardware of the Arduino, it depends on the hardware itself, since in most cases the normal IO hardware is internally not connected to the pin, when using this hardware. For example: The internal pullup resistor will not be active, when doing an analog measurement with the ADC (like via analogRead()).


text:
Arduino code crashing
I am writing an SIM900A + arduino(Arduino UNO with Atmega 328P) code to just send the current time stamp every 20 minutes.
The code keeps crashing in the SendMessage() function as the setup prints keep coming again and again. Please let me know what I am doing wrong. Thanks in advance
#include <SoftwareSerial.h>
#include <LowPower.h>
SoftwareSerial mySerial(9, 10);
char msg;
char call;
int ctr;

#define TIME_STR_LEN 100  // the actual number of characters for date and time

char timeStamp[TIME_STR_LEN]; // holds the time string

void setup()
{
  mySerial.begin(9600);   // Setting the baud rate of GSM Module
  Serial.begin(9600);    // Setting the baud rate of Serial Monitor (Arduino)
  Serial.println("GSM SIM900A BEGIN");
  mySerial.println( "AT+CLTS=1");
  delay(1000);
  ctr = 0;
  delay(10000);
}

void loop()
{

  if(mySerial.available()>0)
  {
    while (mySerial.available()>0)
    {
      mySerial.read();
    }
  }

  if (ctr%1 == 0)
  {
    delay(1000);
    SendMessage();
    delay(100);
    ctr = 0;
    Serial.println("just sent a message");
  }
  delay(60000);
  ctr++;
  //LowPower.idle(SLEEP_8S, ADC_OFF, TIMER2_OFF, TIMER1_OFF, TIMER0_OFF, SPI_OFF, USART0_OFF, TWI_OFF);
}

void SendMessage()
{
 mySerial.println( "AT+CCLK?" );
 delay(2000);

 int i = 0;

 if (mySerial.available()>0)
 {
      while (mySerial.available()>0 && i < TIME_STR_LEN)
      {
        timeStamp[i]=(mySerial.read());
        i++;
      }
  }
  delay(2000);

  mySerial.println("AT+CMGF=1");
  delay(1000);
  mySerial.println("AT+CMGS=\"xxxxxxxxxx\"\r");
  delay(1000);
  mySerial.println("Motor is ON ");
  delay(100);
  mySerial.println(timeStamp);
  mySerial.println((char)26);// ASCII code of CTRL+Z
  delay(1000);
}

Might be a brownout. Are you sure your power supply is powerful enough? The SIM900A needs quite a lot of current.

Currently I have just powered the sim 900A using the 5V and GND pins of the Arduino

And how is the Arduino powered? We need to know the maximum current and also how the power supply is connected (though barrel jack, through USB or directly to the 5V pin)


text:
Arduino UNO and PCA9685 - Problem with external power supply
I am totally desperate and hope you can help me.
I've been building a project for a while where I have to control several servos. For this I bought some MG996R servos and a  PCA9685 16-Channel Servo
Driver board. Furthermore, I bought a suitable power supply (DV 5V - max 3A).
First, I connected my controller and the board as follows and attached the power supply at the intended place:

Everything worked as desired and I could control e.g. one servo with this example script.
#include <Wire.h>
#include <Adafruit_PWMServoDriver.h>

Adafruit_PWMServoDriver myServos = Adafruit_PWMServoDriver();

#define SERVOMIN  150
#define SERVOMAX  600

uint8_t servonum = 0;
uint8_t numberOfServos =  1;

void setup() {
  myServos.begin();
  myServos.setPWMFreq(60);
  delay(10);
}

void loop() {
  myServos.setPWM(0, 0, 500);
  delay(1000);
  myServos.setPWM(0, 0, 300);
  delay(1000);
}

Then I tried something and reconnected a few cables while the power supply was still on (my bad) - after that no servo moved with the original setup (see picture above). After that I tried to find the broken part but couldn't find any - so I bought a new Arduino, PCA board and power supply to try and find the error - unfortunately without success.
Then I found out by chance that the servos move again when I connect the ground of the external power supply to the Arduino and plug the positive pole of the power supply to the V+ with the PCA9685. That is,

I ordered a  pack of three new PCA9685s and again same problem - the servos no longer move when using the designated place for the power supply on the PCA9685 board - what is going on? Can anyone explain this and help me where the problem is?

measure voltage at arduino

what are your thoughts? what voltage should I measure?

power for arduino as you run motors, in each the working and failing configurations.  there are only 4 or 5 leads, at least one of which is ground so you could just measure everything one at a time and see the difference.


text:
Dual Channel Reading with 16 bit AD7705(SPI)
I want to read 2 separate voltage readings by AD7705 ADC and send the data to Arduino(Master). What is the correct program flow should I implement to get dual-channel operation working. How data will be sent to master when both the channels are converting the voltage.
Thanks in Advance.

the data would be sent one bit at a time, since the data path is serial ... it is unclear what you are asking

Correct flow? Switch to channel 1, perform conversion, read data... Same for the second channel. And repeat

"How data will be sent to master" is controlled by the master. That's why it is called master. What's your question/problem?

Thank you for your response. I understood.


text:
Receiving half the value of Reference Voltage in AD7705?
I have a doubt in the AD7705 library AD7705 Library Link when I am declaring a reference voltage of 5 V and giving a reference voltage of 5 V to IN1+. On the serial monitor, I can see ADC conversion from 2.5V to 5 V when I vary the potentiometer.
whatever reference voltage I am giving it is divided by 2.
What parameter should I change to get full-scale voltage reading?
Thanks in Advance!

it is more than divided by two ... please include the schematic diagram of your circuit

If you saying you have a potentiometer, it is likely you had a voltage divider in your circuitry, and you need to convert your ADC reading to get the actual value.


text:
Building RS485 serial to USB adapter with digispark
Is it possible to build an serial-adapter with digispark board?
Like: Embedded System with 2-wire RS-485 Port connect to my digispark board. Digispark Board is connected via USB to my Computer (running Linux tty or Windows COM Putty Interface)
I also own a Raspberry Pi. I'm very new at this thing, so maybe there is a way to convert the RS485 signals to monitoring my devices with my computer?

Yes. However; you state that you are 'very new at this thing', you may want to start with blinking LED's and/or find a tutorial for what project you're thinking off; so you can follow along easily.

I just started with coding digispark, like with these blink led or some other things, but ich dont know where to find the right keyword or tutorial with this serial COM connectors.

There are some good books available to help. There is the Raspberry Pi cookbook and the Arduino cookbook. These will take you from the very beginning to the point where you can make your own designs and they will work.

I would steer you away from using something that has a chip with neither a USART nor USB hardware for the purposes of making something like that. The ATTiny85 that's on the Digispark has USI (Universal Serial Interface), which is really more of a USART construction kit. The USB support it has is bitbanged and somewhat unreliable.
If you do go in this direction and want a small Arduino type board like Digispark, the "Beetle" ATMega32u4 based boards are a better choice.  It has a native USB interface, and a proper USART to hook to an RS-485 driver.
The chip also has a bootloader section; it is difficult to corrupt your own sketch.  It also has more memory, not that you necessarily need it.


text:
Photoresistor help
I'm a newcomer to Arduino, trying to read analog values from a circuit with a photoresistor. I believe I am using a 1-ohm resistor
The problem I am having is that my photoresistor does not seem to be working, or my circuit is wrong. When I run the below code on my Nano, my Serial monitor constantly prints 1023. When I cover the photoresistor completely with my finger, the value dips down to 900-950, but then jumps back up to 1023. It dips down to 900-950 again, and jumps back to 1023. This happens continuously.
Here is my code:
void setup()
{
  Serial.begin(9600);
}

void loop()
{
  int value = analogRead(A0);
  Serial.println(value);
  delay(20);
}

Here is an image of the circuit I am using. In my case, I am using a Nano instead of Uno.

I ran the above code on the virtual circuit above, and it works as expected. However, on my physical device, the phenomenon I explained above occurs.
Is there something wrong with my circuit? Could it be an issue with my photoresistor?

the photoresistor is shorted ... please investigate how a breadboard is constructed

Thanks for the reply. What does it mean for a photoresistor to be shorted?

Also, try a 10 kΩ resistor.

Shorted means there is a flow from VCC (voltage, like +5V for Arduino) with no resistance to GND. This means a lot of current will flow, which might damage or at least make components not working the way they should. Check first how a breadboard works.

shorted means that there is a conductor, such as a wire or breadboard bus, connected from one pin of the sensor to the other pin of the sensor ... this effectively removes the sensor from the circuit, because all of the current in the circuit will flow through the short, bypassing the sensor

Use your ohm meter and check it dark and light that will tell you it is working. Also the resistance (probably 10 or 100K) needs to be relative close to your resistor. Do not expect a lot of voltage swing.

If you pealed the backing off the bread board you will find that you have plugged in your green, red and photo resistor wires into one piece of metal.  This means they are shorted together and as such do not work as you might expect.

Also, be aware that photo resistor or cadmium sulfide cells are slow to react to changes in light.  Sometimes taking about a second to fully change to a new resistance.  If you need a faster response consider using a photo diode or photo transistor.


text:
How do I convert 0-5v PWM to a 0-12v PWM
I have a Arduino which I would like to use to control a 12v PWM fan for speed control.
I know about the 0-3.3v to 0-5v logic level shifter, is there a similar option for 0-5v to 0-12v? Or is there a circuit using a IC that I need to make?
Thanks in advance for your help.

It your on about a 4 wire PC fan the control signal is ttl compatible not 12v.

This unfortunately isn't for a PC fan, this for a large blower unit for air circulation. Thanks though

@MrEditor97, what kind of current will this blower need? I've added an answer and if it is high current (10A or more), I recommend the Pololu driver in my answer, for sure.

...or if you want, you can use a Brushed ESC (Electronic Speed Controller) as well, and feed it a servo signal. It will handle the low-level PWM for you. I just added this to my answer.

@MrEditor97 For future... If you ask some question that is not in common measurements like "yours big blower", You have to mention it in your question that your project is about large machine with higher power comsuption, otherwise do not expect relevant anwser

Related: here's my answer to another question which answers your question. Replace the (relay + R2) in my answer with your motor and this is also a perfectly legitimate circuit to solve your problem. The 5V here in this circuit to the transistor base would be replaced by your 5V logic level PWM signal coming from your Arduino. I also go over calculations and how to size all components: https://arduino.stackexchange.com/questions/77600/switching-a-solenoid-using-arduinos-5v-output/77602#77602.  Try a high-current TIP120 NPN BJT 5 Amp cont. transistor.

Cheers, I will take your advice on board if I have another question! Thanks. I didn't have the serial number of the fan until today, now I have that I have checked the spec, and a low powered option is suitable as it only requires a PWM signal to control the speed the rest is done with its on-board controller - no more than a 0.5mA signal is required. So I believe a transistor method is suitable for this application

Are you just driving the PWM input on the fan or are you driving the fan directly?

@copper.hat, see his latest comment just above yours. He states he's driving the PWM input only, so low-power, low-current PWM signals to an already-existing motor driver is all he needs it turns out. He's not driving the motor directly.

@GabrielStaples Then the answers below seen needlessly complicated to me.

@copper.hat. Unfortunately, every one of the answers below were written without that information, since that info. was only just provided. Most of the answers assumed the motor was a 2-wire brushed DC motor which needed to be driven directly, so that's what they are all (or almost all) answering.

Did you make sure the fan doesn't have an open drain input for pwm control?

I advice you to learn about basics of how to connect external components to MCU.
Anwser to your question is simple transistor amplifier... So you can use bipolar transistor (NPN/PNP) or MOSFET... MOSFETs is better for switching like your case, switching via PWM.
If you switching inductive load with MOSFET like motors or coils, don't forget add antiparallel flyback diode. Otherwise your MOSFET will burn out.

If you need switching with higher frequency or load with more voltage or power I advice to use push-pull logic to drive mosfet gate.
Something like this:

If I was to use a MOSFET, is there a specific type you can recommend? Thanks for your helpful answer!

I use very often IRF540, but try to lookup logic-level MOSFET, It is very handy because gate voltage is 5V so it is compatible with MCUs... logic-level MOSFET are whole sieres of IRL mosfets... Take a look at this link https://circuitcrush.com/arduino/2017/06/02/logic-level-mosfets-irl-or-irf.html

For lower currents (up to several amps vs dozens of amps), NPN BJT transistors, especially Darlington transistors such as the TIP120 NPN BJT 5 Amp continuous one here, are easier to use and drive than MOSFETs.

How does this answer relate to driving a PWM input on a fan? The OP is not trying to drive the fan motor, just the PWM input.

As far as I can tell the Arduino does not have open collector outputs, so you can mimic one as follows. The following inverts the Arduino output signal, so some adjustment is needed there when generating the PWM signal.
Excuse the rather gross schematic. I can't find any scaling parameters.
The particular resistors values are not terribly important, mainly to limit current.

simulate this circuit – Schematic created using CircuitLab

This would totally work, but has the downside of being inverting, and the even bigger downside of passively pulling the output up to 12V through a large R1 resistor, which results in a very weak, rounded edge and slow rise-time. This limits the possible PWM frequency a lot. So, you have active drive to LOW, but passive pull up to HIGH. To solve this problem you have to add enough transistors that in the end you create a half H-bridge, which led me to my "TLDR" answer here: https://arduino.stackexchange.com/a/78569/7727: just buy a motor driver H-bridge from my "Option 2" section and be done.

He is driving a fan not a Tesla. The stray capacitances here are negligible, you don't need microwave frequencies for fan PAM.

You'd usually use a transistor to do that.

simulate this circuit – Schematic created using CircuitLab
SW1 is your microcontroller creating the PWM signal.

use a low side switch for a more reliable transistor turn on

This circuit won't work. To turn the 2N3906 OFF you must set the input to its base to 12V to be equal to the voltage at its Emitter, thereby causing the current to stop sinking from Emitter to Base, but, you're driving the base with only 5V, meaning you can never turn this circuit OFF. That's not good.

You must either add extra transistors and drive circuitry to make it work, or switch to an NPN instead of a PNP BJT transistor. For an NPN, connect the Emitter straight to GND, and put the load between 12V and the Collector. Then it works just fine.

Here's my answer demonstrating a proper circuit with NPN BJT transistor: https://arduino.stackexchange.com/questions/77600/switching-a-solenoid-using-arduinos-5v-output/77602#77602.

Unless the output power is to be used to drive something, it is a bad idea to use BJT. MOS is way more reliable with lower gate current and gate capacitance. This is exactly the opposite of the truth. BJT doesn't have a Gate, nor does it have Gate capacitance. It has a Base, and the Base capacitance is so insignificant it isn't even mentioned on a BJT datasheet. MOSFETs, however, have very large Gate capacitances on their datasheets. The tradeoff is power and current. BJTs drive up to ~5A max (ex: TIP120) for the same physical size MOSFET which could drive 60A (ex: IRLB8721).

@C.Koca, this is getting really painful. MOSFETs are typically used low power logic circuits? True, in part I'm sure because they don't bleed current. They are voltage-controlled, not current-controlled, so they don't require continual current flow to stay on, unlike BJTs. Because MOSFETs allow faster switching. I'm not sure this is true. hence lower gate capacitance very false. and lower power very true, because they (MOSFETs) are voltage-controlled, not current-controlled (BJTs are current-controlled, and hence continually bleed power just to stay on).

You are denying physics what it is due.I implore you: please seek truth.This book (ISBN-13: 978-0199339136),"Appendix G: COMPARISON OF THE MOSFET AND
THE BJT" (here) bipolar transistor amplifiers have superior high-frequency performance compared to their MOS counterparts. (Ex G.3: NPN BJT is higher freq: f_T: 15.3GHz vs NMOS: f_T: 9.7GHz).But MOSFETs have extremely high input resistances and an almost zero input bias current

This applies too, and is true: No, BJT has less extent than MOSFET because BJT is used where we need more speed. But MOSFET is used where we want less power dissipation, low operating voltage, less noise, simple manufacturing process, low chip area and easily scalable.

@C.Koca ... so many wrong things in what you continuously post. Your arguments are too accademic, the suggested circuit in the npn/nmos version is just fine, at least in this application!

@C.Koca oh, and MOSFETs are not suitable for high power? Lol, I bet you blew up a lot of BJTs in your life

Note: my entire answer below assumes you need to drive a 2-wire brushed DC motor (or similar load, such as an audio speaker) directly, with real power and real current. That is what my entire answer is based on. However, after I wrote my answer, the OP posted this in a comment under his question (emphasis added):

I didn't have the serial number of the fan until today, now I have that I have checked the spec, and a low powered option is suitable as it only requires a PWM signal to control the speed the rest is done with its on-board controller - no more than a 0.5mA signal is required.

So, although my answers below will still work to provide an output PWM at, lets say, 12V, from an input PWM at 5V, they are intended to drive a 2-wire brushed DC motor directly with real power and real current. The fact that they can also provide an output PWM signal at 12V is incidental, but just as applicable.
Also, it is important to note that all my answers below are expected to be usable up to a few dozen kHz max PWM frequency, unless otherwise stated on the product datasheets--Ex: many high-end Pololu brand motor drivers (H-bridges) I recommend below can be driven with up to 100kHz PWM frequency since they use such high-quality and fast MOSFET Gate driver circuits with both high-power active Gate drive HIGH and active, high-power Gate drive LOW in their H-bridges.

TLDR;
Jump straight down to the section titled "Here's some H-bridges you can buy", in the "Option 2" section below. Buy one of those and be done.
Reminder: on any H-bridge, when you drive a PWM to the input at 5V with a certain duty cycle and frequency, an equivalent or almost-equivalent PWM output at voltage level Vsupply will occur on the H-bridge output. This is the exact purpose of the half-H-bridge. And, this, in addition to allowing bi-directionality of power, current, and voltage, is the exact purpose of the full H-bridge. PWM output freq from the H-bridge will be exactly identical to the input PWM, and PWM duty cycle will be almost identical, with output PWM waveform distortion increasing as PWM frequency is increased.
Option 1 of 3: [custom circuitry] The Electrical Engineer / "very curious hobbyist with lots of time" answer:
I've upvoted @Sahasrar's answer. If you haven't taken a look at it, you should. It fits squarely into this "Option 1" category.
However, in his first image, when controlling pin D7, the MOSFET gate is actively driven both HIGH and LOW with a max (initial) current of I = V/R = 5V / 100 Ohms = 0.05A = 50mA, which is good, but kind of weak (a good MOSFET gate driver is more like 500~1000mA drive current). This is also exceeding the 40mA max current rating of the Arduino pin, so I recommend you choose a slightly bigger resistor. The resistor here is to limit current to not damage your Arduino pin when charging and discharging the Gate capacitance of the MOSFET, which capacitance is significant enough for MOSFETS (but NOT BJT transistors), that it is even listed as a parameter in a MOSFET transistor datasheet (but not in a BJT transistor datasheet). WithOUT this Gate resistor, each time you drive the Gate HIGH or LOW, you'd otherwise have the equivalent of a momentary instantaneous short through the Arduino pin, which could damage the pin.
Also, you have to be sure to use a Logic-Level N-Channel MOSFET which can be driven with a gate voltage as low as 3.3V~5V instead of requiring more like 10V~12V.
So, with @Sahasrar's first circuit, the max PWM frequency you can use is probably a few dozen kHz.
If you need to drive higher PWM frequencies, the solution is to use the push-pull logic circuit which @Sahasrar shows next instead. But, you have to fill in the blanks: choosing parts, doing calculations, having advanced knowledge.
In both cases, you must also be sure to use a flyback diode to snub inductance-induced voltage spikes!
Option 2 of 3: [just buy an H-bridge DC motor driver] The normal hobbyist / time-constrained-individual answer:
So, the quick solution is to just buy a motor driver instead and be done!
You can use any H-bridge for a 1-channel (1 device) bi-directional drive, or for a 2-channel (2 separate devices) uni-directional drive.
Or, you can use a half H-bridge for a 1-channel uni-directional drive.
H-bridges are frequently called "brushed motor drivers". They handle all the fancy Electrical Engineering circuitry for you.
H-bridges are excellent for driving things like:

brushed, NOT brushless, DC motors
high-power LEDs, assuming you have a means of current-control too, such as a large passive power resistor, or current feedback control loop and control code
speakers (for tone's, beeps, or digital PWM-based [NOT analog-amplifier-based] music, voice, or rich audio). Ex:

tone library

[ok] tone() library
[best] toneAC() library

Example siren project I did with toneAC library, a large speaker, and a custom driver or H bridge:

https://www.electricrcaircraftguy.com/2016/01/arduino-playing-siren-sound.html
https://www.youtube.com/watch?v=anuan0oEOQw&feature=emb_logo
https://www.youtube.com/watch?v=y31gM3m3VJI - final project video demo: siren

music/rich audio PWM-based library

[excellent] TMRpcm library

Here's some H-bridges you can buy:
When searching for these things, recommended search terms include "DC motor driver" or "h bridge". Even if you plan to drive an LED or speaker with it, these are still the correct search terms and parts. Just make sure what you buy accepts PWM input as the control signal is all, and that this PWM input means true PWM, NOT a servo "PWM" signal, which is very different.
Just buy one of these and be done:

Cheap $1 L9110S H-bridge:

Ebay search for "arduino h bridge"
L9110 datasheet

2.5V to 12V supply
800mA max continuous current per channel

Cheap $3 L298N H-bridge (much more powerful):

Ebay search for "arduino h bridge L298"
Example specs sheet: http://www.handsontec.com/dataspecs/L298N%20Motor%20Driver.pdf

3.2 to 40V supply
2A peak current
20W max power

High-end, reliable, very-well-engineered DC motor drivers/H-bridges by Pololu robotics company:

See the full list of motor drivers here! https://www.pololu.com/category/11/brushed-dc-motor-drivers
Ex: $40 Pololu G2 High-Power Motor Driver 18v25

6.5V to 30V supply
1.8V, 3.3V, or 5V logic signals
25A max continuous current
up to 100kHz PWM operation, because they have excellent MOSFET gate drivers to minimize MOSFET time in the ohmic region, and therefore MOSFET heating!
If you're in a hurry and want high-quality, Pololu is an excellent choice!
Tiny! 1.3" x 0.8", and no heat sink required, again, because of their excellent MOSFETS and MOSFET gate driver circuits.

Option 3 of 3: [Radio Control brushed ESC (Electronic Speed Controller)] (easiest of them all!)--preferred by people with RC vehicle experience and/or who need really high power
Important: since this option does NOT give you the low-level control over the PWM output directly, these controllers can NOT drive speakers for audio, whereas Option 1 and Option 2 drivers above can!
I'd be remissed if I didn't include this answer as well, since this is one of my specialties. This is the easiest by far! Its only downside is it gives you less fine-tuned control than controlling the low-level PWM output to the motors directly, as you can do with the motor drivers above, versus the motor controllers below. Another advantage of the hobbyist RC brushed ESCs below over the Pololu-type robotics motor drivers above is power and current: the above motor drivers from Pololu peak out at 25A continuous, for instance, whereas some RC brushed motor controllers, some less-powerful examples of which are shown below, can drive as much as 100~200A continuous, which is HUGE.
Just buy a Radio Control (RC) brushed ESC and feed it a servo PWM signal via the Arduino servo library, NOT a true PWM signal with analogWrite()!
You give it a servo signal, and it generates the low-level PWM to the motor automatically using its internal microcontroller and MOSFET driver circuitry, usually on the order of 8kHz~16kHz PWM output frequency. Many of these types of ESCs use the ATmega168 mcu internally.
For a single-direction ESC, such as for RC airplanes, a microsecond servo value between 700~1300us is 0% throttle, and a microsecond servo value between 1700~2100us is 100% throttle.
For a dual-direction ESC, such as for RC cars, with both forward and reverse, a microsecond value of ~1500us is 0% throttle, with ~2000us or so being 100% forward throttle and ~1000us or so being 100% reverse throttle.
Sample code:
#include <Servo.h>

Servo brushed_motor;

void setup()
{
  brushed_motor.attach(9); // pin 9

  // ~0% throttle (0% output PWM duty cycle), depending on ESC
  // calibration, and assuming a forward-only ESC for RC airplanes
  brushed_motor.writeMicroseconds(1000);

  delay(2000);

  // ~100% throttle (100% output PWM duty cycle), depending on ESC
  // calibration, and assuming a forward-only ESC for RC airplanes
  brushed_motor.writeMicroseconds(2000);
}

void loop()
{
    // whatever you need here
}

To calibrate one of these ESCs to whatever throttle values you want, just set it to 2000us (full throttle) BEFORE you turn it on (careful--just in case it decides to go full throttle instead), then power it up, and it will register that as "full throttle". Next, withOUT powering it off, set it to 1000us (0% throttle), and it will register that as 0% throttle. Now, it is calibrated to have 1000us be 0% throttle and 2000us to be 100% throttle. If using an RC car brushed ESC instead of an RC airplane brushed ESC, you may have to play with it, do some research, and read its manual to get what you want, since 1500us might be considered 0% throttle, with 2000us being 100% forward throttle and 1000us being 100% reverse throttle. So, do the research.
In either case, here's some brushed RC ESCs which can drive motors and blowers or whatever just fine too.

HobbyKing:

Brushed RC CAR ESCs on HobbyKing

$12 45A ESC, 2S LiPo (6V to 8.4V) max here
$40 80A continuous, 400A split-second peak (yes, these numbers seem legit to me), 2-3S LiPo (6V to 12.6V) here

These are just a couple examples. RC ESCs like these are designed to be really high power for high-end RC vehicles which can go up to 25~100mph sometimes, and be quite large. Do some research. Brushed RC ESCs are sold in many places. HobbyKing has the best prices in the industry for these types of things, with generally good to very-good quality parts.
Related:

[my answer]  Switching a Solenoid Using Arduino's 5V Output?

Here's my answer to another question which answers your question. In the diagram below, from this other answer, the relay + R2 is the load. Replace this load (relay + R2) with your motor as the load instead, and this is also a perfectly legitimate circuit to solve your problem. The 5V here in this circuit to the transistor base would be replaced by your 5V logic level PWM signal coming from your Arduino. I also go over calculations and how to size all components. Try a high-current TIP120 NPN BJT 5 Amp continuous transistor in place of the 2N3904 in my circuit, and be sure to redo the calculations to size your base resistor, R1.
Note that this circuit allows your Arduino pin to actively drive the output both HIGH and LOW, but since its through this (relatively small) base resistor, it's probably only good for PWM frequencies up to a few dozen kHz or so. An oscilloscope used to look at the output would make this clear. Increase input PWM frequency until output PWM waveform distortion becomes significant.

@C.Koca, your comment isn't correct. L298 is an H bridge. And, if you supply an L298, or any other H bridge, with 12V, and then PWM the logic input side with 5V, then you get the 12V output side with an identical output PWM, except at 12V. Remember, an H bridge is just 4 transistors set up in two complementary pairs designed to drive a single reversible channel in forward and reverse, or two non reversible channels to drive two separate motors in one direction only.

I can update my answer with exact wiring details if you'd like me to. I've done this on many projects in the past, used H bridges often, and even designed them from scratch. One H bridge can dual drive one speaker, one dual direction DC brushed motor, or two unidirectional DC brushed motors. Also, he mentions under his Question it's a large blower unit. My answer assumes it's a 2 wire DC brushed motor he's driving. Unless he tells me it's a 3 or 4 wire motor, my answer is correct.

H bridge is a fancy word for couple of BJTs. No, "H-bridge" is a very specific word to mean 4 transistors arranged in two complementary high-side + low-side pairs, allowing dual-driving 1 bidirectional 2-wire motor or speaker, or 2 separate unidirectional 2-wire motors or two single-driven speakers. An H-bridge can be designed with either MOSFETs or BJTs, so it implies nothing about being made with BJTs. Motors are driven usually with 8kHz to 16Khz PWM frequencies, rarely ever above 100kHz due to H-bridge limitations and motor inefficiencies/losses which increase with PWM frequency.

@C.Koca, please quit commenting. Nearly every single comment you leave is at least partially incorrect, and you're sowing misinformation wherever you go. You say some truth, some misinformation, some truth, some misinformation, and are seriously confusing anyone reading your comments. Here's a Darlington: https://en.wikipedia.org/wiki/Darlington_transistor. It is a BJT which feeds the base of a BJT. Here's an H bridge: https://www.build-electronic-circuits.com/h-bridge/. It has zero BJT Darlington pairs in it. And, an H-bridge can be made of MOSFETs OR BJTs. A Darlington refers to BJTs.

MAX232 drives low-power signals. L298 or other H-bridges drive real power & current. Signal drivers always have better, more square output than real power drivers, because real power drivers have bigger components to deal with. I have an oscilloscope. I've looked at the PWM output from H-bridges. Please quit sowing misinformation.

Also, my circuit at the bottom of my answer is neither an H-bridge NOR a half-H-bridge. It is a circuit for a different answer, which happens to have some overlap with this answer, and it has pretty good rise time and fall time, since it is actively driven both HIGH and LOW, albeit through a (not large) base resistor, meaning its PWM output would be good only up to a few dozen kHz or so.

Let us continue this discussion in chat.


text:
Wire Halloween Wolf to howl with Arduino motion detector
I bought one of those Home Depot halloween wolves that howl. You can control it with a push-button to be on, or off. It has its own power source via 3 AA batteries that power the howl sound, red eyes and move the jaw.
I'd like to make it motion sensing using the Arduino motion detector.
I thought that I could just cut and splice the wires connecting the button to the wolf to Arduino leads, then use digitalWrite to turn it on/off based on distance detection but it's not working.
The motion detection is working fine, as I set it up like the motion alarm demo. A red LED lights up at the correct distance as well.
Arduino Setup:
pin 10 to J14
J16 to negative
E14 to wolf
E16 to wolf
I'm not sure which wolf wire is +/- so I've tried both
Code:
const int trigPin = 11;           //connects to the trigger pin on the distance sensor
const int echoPin = 12;           //connects to the echo pin on the distance sensor

const int redPin = 3;             //pin to control the red LED inside the RGB LED
const int wolfPin = 10;         //pin that will turn on the wolf

float distance = 0;               //stores the distance measured by the distance sensor

void setup()
{
  Serial.begin (9600);        //set up a serial connection with the computer

  pinMode(trigPin, OUTPUT);   //the trigger pin will output pulses of electricity
  pinMode(echoPin, INPUT);    //the echo pin will measure the duration of pulses coming back from the distance sensor

  pinMode(redPin, OUTPUT);
  pinMode(wolfPin, OUTPUT);
}

void loop() {
  distance = getDistance();   //variable to store the distance measured by the sensor

  if (distance <= 24) {

    analogWrite(3, 255);
    digitalWrite(wolfPin, HIGH);
    delay(5000);

    digitalWrite(wolfPin, LOW);
    delay(1000);
  } else {
    analogWrite(3, 0);
  }

  delay(50);
}

I know there's possibility one/both of my spliced wires aren't working, but I don't think so - I'm new, so it's most likely I have so lack of understanding on something.
Please help, Halloween is approaching...

You need to reverse engineer how the button is wired in the wolf to some degree. Controlling the wolf is certainly possible with the arduino, but you can't randomly connect  wires and buttons and axpect it to work.

bridge the button with relay contacts

I agree with @jsotola. I think you can also use a small signal transistor for this. Like the 2n2222a, and wire the base pin of the transistor to your gpio "wolfPin".

@SimSon I agree with you, please do a electrical schemat of the wolf so you can make right decision for how to control it. To just randomly connect wires is often the cause for fires and smoke ;-)

By the way, cool project, check in on Arduino "touch sensor" feature, then you can add other cool effects.


text:
Low power USB C power supply
I am searching for a tiny board to that accepts an usb-c cable and outputs 5v.
To my understanding, for the few hundred milliamps two 5k1 resistors on the board would suffice. PD is not needed.
I already bought this, but sadly it's too big. Also, I don't need any data pins, just 5v and -.
Can anyone recommend such a board to power a tiny circuit?

If you can't find one, design your own.

I would, I just  don't have the equipment to assemble it. Also, the project is really not that important...

Cut the end off a USB C extension cable and wire it in directly.

takes too much space, sadly...

More space than the cable you'd be plugging in anyway?

by extension cable you mean a type c with male on one end and female on the other?

Yes. Have the socket "remote" from your space constrained device.

I see. Sadly, that defeats the purpose in my case. I could just aswell cut a male-male cable and hardwire that. Although it's quite creative.

Have you considered not using USB C? There are plenty of other small connectors.

Sure. Seems like I am falling back to usb micro. I thought that if I am already building a device, it could be C aswell..

It would make sense from a future-proofing PoV. It's still not common in the arduinosphere though - there's not many boards that use it. I think I only have 2 USB C cables in my possession, and one of those is for a Pi 4.

I'd cut that board. Solder some wires to the GND and VCC planes. I don't think those resistors are needed if you use less than 100mA. Though I'm not that familiar with USB C. You might be able to move them with some creative soldering.

sadly, usb c doesn't provide 5v just like that, so some sort of configuration is needed...


text:
Which sensor bus best to use?
I am working on a project which requires a dozen VL53l0X I2C-TOF sensors to be polled by one master MCU over a few meters of cable.
Thus, I decided to accompany each TOF by an Atmega8 acting as a gateway between the TOF and a Modbus (using a MAX485), which is managed by an ESP32 (the master). Since I require fairly low latency (~10 reads / sensor / second) I am a bit disappointed by the Modbus RTU performance (mostly caused by the forced 1.75ms delay between frames).
My question: Is there any quicker, more suitable, Atmega-bearable bus protocol for long distances? Ethernet is sadly not an option due to the limited slaves computing power and cost...

MODBUS is just a communication protocol that runs on an existing physical layer - RS485. You don't have to run MODBUS over RS485 - you can run whatever you like over RS485, it's just serial.

CAN for the Phy (physical) layer would be good for several thousand feet. You can use whatever baud and protocol on the CAN layer you like within reason. I am assuming (maybe in error) that they all communicate on the same bus. This CAN Phy was designed for this. It would be possible for you to write your own protocol and simply address each by a unique number or whatever. There is also the option of using a CAN controller but I think that would be a lot of time not needed to design your solution. By placing a Atmega8 at each sensor opens up a lot of possibilities for you.

So, am I understanding it right that each slave would need it's own Object-ID?

Not sure what you are asking. Each simply needs a unique identifier so you can address them individually. You can do an 'all call if' you like. The address can be as simple as A, B, C etc then you can see it on the bus monitor. For example, when you address 'A' it responds with its data. You may have to add a preamble so the slaves know it is a command not data. No suggestions as I do not know what the data stream will look like. Keep It Simple it is much easier to troubleshoot.


text:
Serial port usage in code
I want to write a function that defines a serial port based on a flag but I'm not sure it's possible.
For example:
void writeToSerial(bool useSerial1)
{
   SerialPortClass serialPortObject; // Is there some way of defining a generic Serial port object and reusing it below?

   if (useSerial1)
   {
      serialPortObject = Serial1;
   }
   else
   {
      serialPortObject = Serial2;
   }

   serialPortObject.write("test123");
}

Does this answer your question? Passing HardwareSerial and SoftwareSerial as a Class Property

According to sources at c:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino\HardwareSerial* (on Windows platform), you can use pointer to Stream class (because Serials are inherited from Stream).
So, your function could look like this:
void writeToSerial(bool useSerial1)
{
   Stream* serialPortObject;

   if (useSerial1)
   {
      serialPortObject = &Serial1;
   }
   else
   {
      serialPortObject = &Serial2;
   }

   serialPortObject->write("test123");
}

Note that the serial port has to be already initialized for this to work, as Stream lacks the begin() method. If you need to call either begin() or end(), you should use a pointer to HardwareSerial.

This is not a proper answer, but rather a suggestion to reconsider your
approach. The code posted in the question is obviously just a simplified
example, and printing “test123” is likely not your final goal. I assume
what you really want to do is print out some information about some
variables. You can then collect these variables into a data structure (a
C++ object) and make writeToSerial() a method of this object. The
object can the be printed like so:
myDataStructure::writeToSerial(true);   // printed to Serial1
myDataStructure::writeToSerial(false);  // printed to Serial2

In this case, what I suggest is to instead explicitly print() (or
println()) the object to the relevant serial port, like this:
Serial1.print(myDataStructure);
Serial2.print(myDataStructure);

This makes the code self-explanatory, and easier to maintain.
Obviously, you cannot just print arbitrary objects this way, as
Serial1 and Serial2 would have no idea about how to serialize them.
But the thing is, you can teach them! Make your class derive from
Printable, implement the virtual printTo() method, and you will be
able to print it to any serial port, LCD, or whatever understands
print():
class MyDataStructure : public Printable {
public:
    size_t printTo(Print& p) const {
        return p.print("test123");
    }
};

MyDataStructure someData;

void setup() {
    Serial1.begin(9600);
    Serial2.begin(9600);
    Serial1.println(someData);
    Serial2.println(someData);
}

void loop(){}

See the answer to Is it possible to print a custom object by passing it
to Serial.print()? for an example with actual data in the
object.


text:
Not sure why eeprom isn't reading back correctly
I'm new to saving data on eeprom and I'm obviously doing something wrong but I'm not sure what.  I have one program which both writes to and reads the internal eeprom on a attiny85 and this seems to work.  However when I try to use this program to write and then remove the power from the attiny, then reprogram it with another program to read the eeprom it gives values of -1 for time and NAN for temperature.
My program which works is as follows, the program to read the eeprom only is the same however I deleted all the sections which write.  If you want me to add that program let me know.
I am using at attinyavr programmer from sparkfun and I have connected pins 3 & 4 on the attiny to an arduino uno which is connected to the serial monitor so that I can see the output (described here:  http://www.instructables.com/id/Easy-ATTiny-Serial-Communication-with-Tiny-AVR-Pro/#CP78RMAJ76GI6JQ)
Feel free to direct me to another answer if someone else has had the same problem, at the moment I think I will figure this out eventually but I suspect it will take me a few days so thought I would ask hopefully it's obvious to someone else.
(I'm aware that the time won't be correct since it should be unsigned long not an int, was just changing it round to test if that was the problem which it seems not to be).
Any help is really appreciated!!! Thanks :)
    /*
ATTINY85 pin 3 -> Arduino Uno pin 0
ATTINY85 pin 4 -> Arduino Uno pin 1
Program choose 1MHz clock
 */

#include <EEPROM.h>
#include <SoftwareSerial.h>
// Definitions
#define rxPin 3     // Make pin 3 on the
#define txPin 4

SoftwareSerial mySerial(rxPin, txPin);

int currentTime;
int getTime;

int sensorPin = 7; // This is the 7th pin on the ATtiny85,
                         // it is an analog input when reading as digital
call it 7? analogpintochannel function
                          // (On the HLT tutorial it is labelled as Pin2: Analog input 1, SCK )
float temperature = -500.00f;     // Create a new float called temperature and give it the value -500 to start with
float getTemperature = -500.00f;
int eepromAddress = 0;       // initialize variable for position in eeprom to store data collected
int getEepromAddress = 0;

// the setup routine runs once when you press reset:
void setup() {
  pinMode(sensorPin, INPUT);    // make pin 7 on the ATTiny an input pin
  mySerial.begin(9600);         // begin software serial at rate of 9600

}

// the loop routine runs over and over forever:
void loop() {

  static int countDataCollected = 0;  // initialize a count variable to count the data collected, static int should set to 0 only first time, second time loop goes round it shouldn't reset to 0

  if (countDataCollected==0) delay(90000); // put delay here so it gives me time to load the read eeprom program if required before it changes the eeprom in case that was the problem.

  if((countDataCollected>=0) and (countDataCollected < 10)) {

    currentTime = millis();
    temperature = analogRead(sensorPin)*5.0/1024.0;  // read value on pin 7, multiply it to find temperature
    temperature = temperature - 0.5;
    temperature = temperature / 0.01;

    mySerial.print("\n\nData number: ");
    mySerial.print(countDataCollected);
    mySerial.print("\tTime: ");
    mySerial.print(currentTime);
    mySerial.print("\tTemperature: ");
    mySerial.print(temperature);
    mySerial.print("\tCurrent eeprom address: ");
    mySerial.print(eepromAddress);
    mySerial.print("\t");
    mySerial.print(getEepromAddress);

    EEPROM.put(eepromAddress, currentTime);
    EEPROM.get(getEepromAddress, getTime);
    mySerial.print("\tGot time: ");
    mySerial.print(getTime);

    eepromAddress = eepromAddress + sizeof(currentTime);
    getEepromAddress = getEepromAddress + sizeof(getTime);
    mySerial.print("\teeprom address: ");
    mySerial.print(eepromAddress);
    mySerial.print("\t");
    mySerial.print(getEepromAddress);

    EEPROM.put(eepromAddress, temperature);
    EEPROM.get(getEepromAddress, getTemperature);

    eepromAddress = eepromAddress + sizeof(temperature); //Move address to the next byte after float 'myfloat'.
    getEepromAddress = getEepromAddress + sizeof(getTemperature);
    mySerial.print("\tGot temperature: ");
    mySerial.print(getTemperature);
    mySerial.print("\teeprom address: ");
    mySerial.print(eepromAddress);
    mySerial.print("\t");
    mySerial.print(getEepromAddress);
    mySerial.println();

    }

  // wait two seconds so as not to send massive amounts of data
  delay(2000);
  countDataCollected=countDataCollected+1;

  mySerial.print("\n\nNext data number =");
  mySerial.print(countDataCollected);
}

See https://stackoverflow.com/questions/36623186/attiny85-eeprom-erase-after-power-lost for an explanation to why eeprom is erased.

@MikaelFalkvidd, thanks!!!, that sounds like it's probably the problem.  I'm just trying to learn how to program the Attiny85 with a bootloader, when/if I do I will get back to confirm that was the reason. (might take a while as I'm in China and need to find out how to order the components I need to build the circuit)

Great that you found a solution. I think you have a better grasp of the solution than I do, so you'll be able to write a higher quality answer :)

@ Mikael Falvidd, I'm not sure, but thanks!! :)

@ Mikael Falvidd  Actually in the end found my comment above about the programmer was incorrect, (such a long time since I asked the question I forgot to try disconnecting the power and when I did the programmer made no difference. Have deleted the comment so as not to confuse other people) but you did direct me the correct answer, thanks!!!, it was fuses that made a difference. Will add answer below, so happy it's working!!

Fixed by resetting the attiny85 fuse to stop the EEPROM being cleared when the attiny was reprogrammed.
As far as I understand (I am a newbie at AVR programming so may be wrong)
The arduino bootloader (in the Arduino IDE) sets the attiny fuses.  One of the fuses that it sets (also the attiny85 default setting) clears the EEPROM when reprogramming.  To see how the bootloader is setting the fuses to you can turn on verbose comments in the Arduino IDE, and run the bootloader. When I ran the bootloader it set the fuses as follows: pattiny85 -cusbtiny -e -Uefuse:w:0xff:m -Uhfuse:w:0xdf:m -Ulfuse:w:0xe2:m
i.e. arduino bootloader settings,
     efuse: 0xff,
     hfuse: 0xdf (need to change to d7),
     lfuse: 0xe2 (affects the clock),
You can use a fuse calculator (http://www.engbedded.com/fusecalc/)
 to determine how to change the fuse settings so the the EEPROM is not cleared.  (In the fuse calculator tick the box for "Preserve EEPROM memory through the chip erase cycle, EESAVE=0").  When the box is ticked the hfuse setting is D7 rather than DF
Also note that the bootloader in Arduino sets the lfuse to 0xe2, this is different from the default (it affects the setting 'Divide clock internally by 8' if 0xe2 is used it's an 8Mhz clock, the default prior to loading the boatloader is 1Mhz). Noting this because I initally reset everything to default and then had clock problems.
The hfuse can be set to d7 by downloading and running the AVR programming software https://sourceforge.net/projects/winavr/ and then setting the fuse using avrdude in a command window.
(more information on AVR setting fuses here http://www.ladyada.net/learn/avr/index.html)
I ran avrdude in a command window with the instruction:
avrdude -c usbtiny -p attiny85 -U hfuse:w:0xd7:m
("-c usbtiny" specifies the programmer used so this may vary, the attiny was connected to my computer USB port using the sparkfun attiny AVR programmer).

The bootloader itself does not set fuses. However, the Arduino IDE's Tools > Burn Bootloader command does set the fuses according to the boards.txt configuration for the currently selected board in addition to flashing the microcontroller with the bootloader.

ok, thanks for the correction! I'm not very clear on how everything works.

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


text:
Arduino mini requires uploading on every power up?
My Arduino mini is experiencing some really strange problem.
I'm using the BlinkWithoutDelay example sketch for testing:
const int ledPin =  13;
int ledState = LOW;             // ledState used to set the LED
long previousMillis = 0;        // will store last time LED was updated
long interval = 1000;           // interval at which to blink (milliseconds)

void setup() {
    pinMode(ledPin, OUTPUT);
}

void loop()
{
    unsigned long currentMillis = millis();

    if(currentMillis - previousMillis > interval) {
    // save the last time you blinked the LED
    previousMillis = currentMillis;

    // if the LED is off turn it on and vice-versa:
    if (ledState == LOW)
        ledState = HIGH;
    else
        ledState = LOW;

   // set the LED with the ledState of the variable:
   digitalWrite(ledPin, ledState);
  }
}

The program basically turns pin 13 on and off every 1000ms.
When I uploaded this sketch into the mini (via Arduino Uno board, sans Atmega chip), the scope reading of pin 13 shows nice square waves (1s pulsewidth, 2s period), as expected.
I then unplug the USB cable powering the mini through the Uno board, wait for a few seconds for the scope traces to settle (I only have an old analog one at hand), and then plug it back in to turn on the board. However, the pin output is different - I now get a train of three pulses (60ms wide, 60ms between pulses) at sporadic intervals.
Uploading the sketch then yields the desired square waves again.
What is going on here? I'm fairly sure the mini has nonvolatile memory and it's intact (otherwise the bootloader through which I upload the sketch would not work).

What does the led do? The led will fade during the bootloader phase. Try disconnecting the scope while power cycling.

There is no LED actually connected. The sketch simply alternates the pin between HIGH and LOW for 1s, and I'm just monitoring the output on the scope.
Are you suggesting that having a high impedance load connected (the scope) to the output during power cycling someone interferes with the Arduino correctly executing instructions?

It shouldn't matter. But then again, your program shouldn't misbehave, like it does, either. Try using a different pin. Also, what happens if you press the reset button (instead of, or after power cycling)?

I've used multiple pins, the behavior persists.
When I press the reset button, there's no output for a little bit, then the same triple-pulses start again.
I'm going to do the same thing on my Arduino Uno, to check if my mini is somehow screwed up.

There was a defective bootloader that shipped on some Arduino devices which caused the symptom you describe. See:
http://forum.arduino.cc/index.php?topic=51172.0
http://forum.arduino.cc/index.php?topic=74090.0
If that's the case, your options are to re-write the bootloader yourself (if you have the capability) or return to the manufacturer.

Thanks a lot for the links. That would make sense, I'll probably flash the bootloader then.

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


text:
How does the FireBeetle ESP32 regulate to 3.3v? (schematic provided)
The FireBeetle ESP32 advertises an input voltage of 3.3v-5v, with an operating voltage of 3.3v.
I tested this with an 18650 lithium-ion battery and can confirm this is true. For 3.3V < Vbat < 4.2V, there is a consistent ~3.295 volts at the 3V3 pin. For Vbat < 3.3V, 3V3 drops slightly under Vbat (approx. -.02V).
I found this odd because the onboard RT9080-33GJ5 regulator has a dropout of about 0.2V to 0.3V, so theoretically the output voltage should drop off steeply for Vbat < 3.6V.
Looking at the schematic, I was unable to figure out exactly how this board is able to regulate to 3.3 volts with essentially no dropout. Is it using some sort of buck converter that isn't mentioned in the schematic, or some other clever circuit?
Any help understanding would be much appreciated!

your question is off-topic here

Answered my own question - I didn't realize that dropout voltage essentially goes to 0 for this regulator when current consumption is low. Pretty neat for low current applications with the ESP32.