body:
So recently I found this tutorial online about the SIM808. It looked super cool so I ordered the sim808 evb 3.2.4 off amazon. Hooked up the module and connected the RX (11) and (10) TX pins.

Here is the code I'm working with tried to follow along as best I could with the tutorial but now I am completely confused, purchased a SIM card activated the SIM card and it seems to be connecting just fine

In the serial monitor sometimes I receive this: 14:05:06.243 -> Init Success, please send SMS message to me!

But most of the time I'm receiving this: 14:04:37.586 -> Sim808 init error

#include <DFRobot_sim808.h>
#include <SoftwareSerial.h>

#define MESSAGE_LENGTH 160
char message[MESSAGE_LENGTH];
int messageIndex = 0;
char MESSAGE[300];
char lat[12];
char lon[12];
char wspeed[12];

char phone[16];
char datetime[24];

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

void sendSMS();
void getGPS();
void readSMS();

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

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

  Serial.println("SIM Init success");

  Serial.println("Init Success, please send SMS message to me!");
}

void loop()
{
  //*********** Detecting unread SMS ************************
   messageIndex = sim808.isSMSunread();

   //*********** At least, there is one UNREAD SMS ***********
   if (messageIndex > 0)
   {

      readSMS();
      getGPS();
      sendSMS();

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

      Serial.println("Please send SMS message to me!");
   }
}

void readSMS()
{
  Serial.print("messageIndex: ");
  Serial.println(messageIndex);

  sim808.readSMS(messageIndex, message, MESSAGE_LENGTH, phone, datetime);

  //***********In order not to full SIM Memory, is better to delete it**********
  sim808.deleteSMS(messageIndex);
  Serial.print("From number: ");
  Serial.println(phone);
  Serial.print("Datetime: ");
  Serial.println(datetime);
  Serial.print("Recieved Message: ");
  Serial.println(message);
}

void getGPS()
{
  while(!sim808.attachGPS())
  {
    Serial.println("Open the GPS power failure");
    delay(1000);
  }
  delay(3000);

  Serial.println("Open the GPS power success");

  while(!sim808.getGPS())
  {

  }

  Serial.print(sim808.GPSdata.year);
  Serial.print("/");
  Serial.print(sim808.GPSdata.month);
  Serial.print("/");
  Serial.print(sim808.GPSdata.day);
  Serial.print(" ");
  Serial.print(sim808.GPSdata.hour);
  Serial.print(":");
  Serial.print(sim808.GPSdata.minute);
  Serial.print(":");
  Serial.print(sim808.GPSdata.second);
  Serial.print(":");
  Serial.println(sim808.GPSdata.centisecond);
  Serial.print("latitude :");
  Serial.println(sim808.GPSdata.lat);
  Serial.print("longitude :");
  Serial.println(sim808.GPSdata.lon);
  Serial.print("speed_kph :");
  Serial.println(sim808.GPSdata.speed_kph);
  Serial.print("heading :");
  Serial.println(sim808.GPSdata.heading);
  Serial.println();

  float la = sim808.GPSdata.lat;
  float lo = sim808.GPSdata.lon;
  float ws = sim808.GPSdata.speed_kph;

  dtostrf(la, 4, 6, lat); //put float value of la into char array of lat. 4 = number of digits before decimal sign. 6 = number of digits after the decimal sign.
  dtostrf(lo, 4, 6, lon); //put float value of lo into char array of lon
  dtostrf(ws, 6, 2, wspeed);  //put float value of ws into char array of wspeed

  sprintf(MESSAGE, "Latitude : %s\nLongitude : %s\nWind Speed : %s kph\nMy Module Is Working. Mewan Indula Pathirage. Try With This Link.\nhttp://www.latlong.net/Show-Latitude-Longitude.html\nhttp://maps.google.com/maps?q=%s,%s\n", lat, lon, wspeed, lat, lon);
}

void sendSMS()
{
  Serial.println("Start to send message ...");

  Serial.println(MESSAGE);
  Serial.println(phone);

  sim808.sendSMS(phone,MESSAGE);
}`

title: Arduino Uno + SIM808 EVB 3.2.4 not working properly?

Answers: 1

body:
I recommend you to use AT command ..then using some kind of library. You need to dig into library for better information.

https://randomnerdtutorials.com/sim900-gsm-gprs-shield-arduino/
Go through this link....this will give you a rough idea.


body:
Is it possible to connect 4 or more Arduinos to a single GSM Module.?
All the Arduinos need to send SMS at a specific time daily.
How do I make sure thet don't time collide with each other, other than sending sms at different times for each Arduino?.
I want the SMS to be queued up, and be sent one by one.

title: How do I connect 4 or more Arduinos to a single shared GSM Module?

Answers: 1

body:
You should consider connecting one Arduino to the GSM module, and connect the 4 Arduinos together using SPI, I2C, or any other inter-hardware comms protocol. Before I knew these options existed, I once wrote a bit of code to send data between Arduinos by having one pin represent the data being sent and another pin changing every time a new bit was available. You could do something similar with an extra line per pairing, so an Arduino could tell the primary that it had new data to send.

Anyway, check out the "Wire Library" - it's basically for this kind of work. I think you'll be happier trying to have one Arduino "in charge" and connected to the CSM while the rest vie for its attention.


body:
I have a Longruner Nano ATMega 328P (copy of arduino nano, main difference being the USB connector, CH340 instead of the usual FT232, from what I could find using google searches).

I wrote a super basic code to test its signal detection capabilities:

```
setup(){
  pinMode(13, OUTPUT);
  pinMode(2, INPUT);
}

loop(){
  digitalWrite(13, digitalRead(2));
}
```

Hard to make it simpler to test a simple thing: when I give a HIGH signal to D2, D13 is HIGH too.

To test it, I used a simple male-male jump cable and connected VIN pin to the D2 one, for a very brief moment. And I notice D13 stays HIGH for around a second (measured with serial, lowest I could get was 996ms after super quickly touching D2 with the jump cable).

I tried to change the pinMode to INPUT_PULLUP following a similar question I found, but it didn't change anything regarding this delay.

Am I doing something wrong? Maybe a wrong configuration? Or is this just a hardware issue due to the fact that I'm using a copy and there's more than just the USb connector that changes?

I can adapt and work with this if it's required, but being able to have an accurate signal detection would help me greatly.

title: Longruner Nano ATMega 328P input stays HIGH for 1s longer than the reality

Answers: 1

body:
Don't use Vin as a logic source. Use the +5V pin.

Also, disconnecting the pin is not the same as grounding it. It is "floating". For a proper test, connect a +5V to the pin, and follow it with a Gnd.

A floating pin has an undefined logic level.

What would work in your case is to have a (say) 1k resistor between D2 and Gnd. That way, the moment you disconnect the voltage input the "pull-down" resistor will return it to 0V.


body:
I'm trying to do wireless thermometer on max31865 arduino and nrf24l01 but I'm having problem sending whole data struct I can send int or char arrays but when I try to send whole struct I got output as
```
id: 131073 temperature: 0
```
Is there error in my code or there is some issue with differences in how arduino and raspberry store data? I don't really have experience in this so my question is how do I send struct that contain two fields of int or there is some better way? I need to transmit id and temperature in one package.

Transmitter code(Arduino)
```
#include <SPI.h>
#include "RF24.h"
#include <Adafruit_MAX31865.h>

#define RREF      430.0
#define RNOMINAL  100.0

typedef struct{
  int id = 100;
  int temperature = 100;
}
temp;

temp data;

bool radioNumber = 0;
int i =0;
Adafruit_MAX31865 thermo = Adafruit_MAX31865(10, 11, 12, 13);
RF24 radio(7,8);

byte addresses[][6] = {"1Node","2Node"};
bool role = 0;

void setup() {
  Serial.begin(115200);
  thermo.begin(MAX31865_3WIRE);
  radio.begin();
  radio.setChannel(125);
  radio.setPALevel(RF24_PA_MIN);
  radio.powerUp();
  radio.setDataRate(RF24_1MBPS);
  if(radioNumber){
    radio.openWritingPipe(addresses[1]);
    radio.openReadingPipe(1,addresses[0]);
  }else{
    radio.openWritingPipe(addresses[0]);
    radio.openReadingPipe(1,addresses[1]);
  }
  radio.stopListening();
}

void loop() {
      data.id = 1;
      data.temperature = 2;
    //int temp = 2; //thermo.temperature(RNOMINAL, RREF);
    Serial.println(temp);
    if (!radio.write( &data, sizeof(data) )){
        Serial.println(F("failed"));
     }
     delay(1000);
}
```
Receiver code(Raspberry pi b3+)
```
#include <cstdlib>
#include <iostream>
#include <sstream>
#include <string>
#include <unistd.h>
#include <RF24/RF24.h>

using namespace std;

typedef struct{
        int id = 99;   // debug value
        int temperature = 99;
}
temp;

RF24 radio(22,0);
temp data;

bool radioNumber = 1;
const uint8_t pipes[][6] = {"1Node", "2Node"};

int main(int argc, char** argv)
{
    radio.begin();
    radio.setChannel(125);
    radio.setPALevel(RF24_PA_MIN);
    radio.setDataRate(RF24_1MBPS);
    radio.setRetries(15, 15);
    radio.printDetails();
    if (!radioNumber) {
        radio.openWritingPipe(pipes[0]);
        radio.openReadingPipe(1, pipes[1]);
    } else {
        radio.openWritingPipe(pipes[1]);
        radio.openReadingPipe(1, pipes[0]);
    }

    radio.startListening();

    while (1) {
            if (radio.available()) {
                int tem = 0;
                while (radio.available()) {
                    radio.read(&data, sizeof(data));
                }
                cout << tem  << "  " << "id: "<< data.id<< " temperatura: " << data.temperature << endl;
                delay(925);

            }
        }
    return 0;
}

```

EDIT:
Ok after running sizeof(data) on both devices, I notice that structs have different size 4 bytes for arduino and 8 for raspberry. So change on raspberry side to
```
typedef struct{
  uint16_t id = 100;
  uintt16_t temperature = 100;
}
temp;
```

And this is working but, may I ask why int have various size on arduino and raspberry?

title: Sending data struct with 2 int fields from Arduino to Raspberry via NRF24L01

Answers: 1

body:
Your problem is that you are communicating between an 8-bit and a 32-bit architecture.

On an 8-bit architecture `int` is 16 bits. On a 32-bit it's 32 bits. Why the difference? Because "it is". It's how it's always been since the dawn of C. The concept of `int` is a flexible idea with no fixed defined size - the size is largely defined by the architecture and the compiler. Although conventions now dictate that an `int` will be 16 bits on an 8-bit system and 32-bits on a 32-bit system.

You can think of it as the integer size being the same as the internal register width of the processor *but with a lower bound of 16 bits*.

This is precisely why the fixed width integer types `uint16_t` etc exist - so that you can enforce the same data size on different architectures.

Incidentally you should also be aware of the *endianness* of your systems. In your case they are both "little endian", but "big" (and even "middle") endian systems also exist.  This defines what order each byte of an integer (and other multi-byte data types) is stored in memory. If you send an integer from a little-endian to a big-endian system and don't apply any transformation to the data to reverse the bytes then the values will be completely wrong.


body:
I was looking for a websocket server for my MKR1000 but nothing I found works.

I tried all the libraries that come with Arduino but half of those don't compile on the MKR1000 and those that do it don't work at all.

Your help would be greatly appreciated!

title: WebSocket Server for MKR1000

Answers: 1

body:
This relatively simple one has always worked for me on several Arduinos (but I haven't tried it on the MKR1000 specifically):

https://github.com/morrissinger/ESP8266-Websocket

I have forked it and made some changes, but nothing fundamental:

https://github.com/ocrdu/NINA-Websocket

Have a go; it will probably work for you. Note that it works on more Arduinos than the name suggests; it's quite universal.


body:
Hi I am doing a project in which I use 2 HC-05 modules and 2 arduino unos driving them. 1 bluetooth module is master and the other is slave. Master module is stationary while slave is moving. If the distance between these 2 modules is less than 1.5 meter, master device turns on a led. If the distance is more than 1.5 meter, the led will not be turned on. This is the basic idea and it works but not as I wanted. I present the code

master device code:

    #include <SoftwareSerial.h>
    //master device code
    SoftwareSerial BTSerial(5, 6); // RX | TX
    #define LED 4
    unsigned long timer = 0;
    unsigned long timeDifference = 0;
    char data;

    void setup()
    {
      Serial.begin(9600);
      BTSerial.begin(9600);
      pinMode(LED, OUTPUT);
      delay(5000);
    }

    void loop()
    {
      BTSerial.write('A');
      timer = millis();
      while(!BTSerial.available()){}
      data = BTSerial.read();
      if(data =='B'){
        timeDifference = millis()-timer;
      }
      Serial.println(timeDifference);

      if(timeDifference < 280){
        digitalWrite(LED,HIGH);
      }else{
        digitalWrite(LED,LOW);
      }
      delay(500);

    }

slave device code:

    #include <SoftwareSerial.h>
    //slave device code
    SoftwareSerial BTSerial(5, 6); // RX | TX

    char data;

    void setup()
    {
      BTSerial.begin(9600);
    }

    void loop()
    {
      while(!BTSerial.available()){}
      data = BTSerial.read();
      if(data =='A'){
        BTSerial.write('B');
      }

    }

So what happens here is that master device sends a char and starts timer. Slave receives the char and send another char to master device. When master device receives char, it stops timer and looks at how much time passed. The problem is that when I put those bluetooth devices together, the time difference is like 280ms. When I move away in the room with slave device, it is still like same. It is not sensitive. What can I do to make this more sensitive? I am waiting for your opinions

title: sensitive distance detection using 2 HC-05 module/ 2 arduino unos

Answers: 3

body:
The approach you're using will not work. You're trying to use speed of light time measurement to gauge distance. There are a whole host of problems with that. First, the clock on the Arduino is not fast enough (high enough resolution). You need accurate, sub-nanosecond time resolution for that (see this video: https://www.youtube.com/watch?v=9eyFDBPk4Yw). Second, BLE is a packet protocol. The overhead and variability of sending packets will totally swamp the **tiny** difference in round-trip time due to speed of light delay.

The usual way to gauge distance with BLE is to measure signal strength. That is also error-prone, but you can at least get rough "immediate", "near", "middle" and "far" distance measurements.

Alternately you could use and ultrasonic range sensor.

body:
In addition to the concerns above, your code won't work the way you want it to. You are initializing timer every loop so the time difference will always be 0. Instead, you should only write `A` from master device when it receives the response `B` and only then reset `timer`.

    void loop()
    {
      while(!BTSerial.available()){}
      data = BTSerial.read();
      if(data =='B'){
        timeDifference = millis()-timer;
        timer = millis();
        BTSerial.write('A');
      }
      Serial.println(timeDifference);

      if(timeDifference < 280){
        digitalWrite(LED,HIGH);
      }else{
        digitalWrite(LED,LOW);
      }
      delay(500);
    }

body:
Your approach is never going to work no matter how hard you try; it's like trying to use a hammer to bake bread!  If you need accurate time-of-flight distance measurements, use a sensor designed to do that, like the [ST Micro VL53L0X time-of-flight IR LIDAR module][1].

  [1]: https://www.fpaynter.com/2020/06/replacing-hc-sro4-ultrasonic-sensors-with-vl53l0x-arrays/


body:
I'm trying to send JSON, but i'm not able to set `Content-Type` header.\
Other commands are successful:
```
[23:49:41:856] AT+SAPBR=3,1,"CONTYPE","GPRS"␍␊
[23:49:41:899] ␍␊
[23:49:41:899] OK␍␊
[23:49:52:327] AT+SAPBR=3,1,"APN","internet"␍␊
[23:49:52:367] ␍␊
[23:49:52:367] OK␍␊
[23:49:59:585] AT+CSQ␍␊
[23:49:59:594] ␍␊
[23:49:59:610] +CSQ: 18,0␍␊
[23:49:59:610] ␍␊
[23:49:59:621] OK␍␊
[23:50:07:449] AT+SAPBR=1,1␍␊
[23:50:08:501] ␍␊
[23:50:08:512] OK␍␊
[23:50:13:900] AT+SAPBR=2,1␍␊
[23:50:13:928] ␍␊
[23:50:13:928] +SAPBR: 1,1,"127.0.0.1"␍␊
[23:50:13:955] ␍␊
[23:50:13:955] OK␍␊
[23:50:21:261] AT+HTTPINIT␍␊
[23:50:21:291] ␍␊
[23:50:21:291] OK␍␊
[23:50:40:284] AT+HTTPPARA="CID",1␍␊
[23:50:40:320] ␍␊
[23:50:40:320] OK␍␊
[23:50:47:652] AT+HTTPPARA="URL","http://127.0.0.1:5000/data"␍␊
[23:50:47:713] ␍␊
[23:50:47:713] OK␍␊
[23:50:54:359] AT+HTTPPARA="CONTENT","application/json"␍␊
[23:50:54:414] ␍␊
[23:50:54:414] +CME ERROR: operation not allowed␍␊
[23:51:06:576] AT+HTTPDATA=38,10000␍␊
[23:51:06:612] ␍␊
[23:51:06:612] DOWNLOAD␍␊
[23:51:12:034] ␍␊
[23:51:12:050] OK␍␊
[23:51:19:386] AT+HTTPACTION=1␍␊
[23:51:19:414] ␍␊
[23:51:19:414] OK␍␊
[23:51:27:747] ␍␊
[23:51:27:758] +HTTPACTION:1,500,290␍␊
[23:51:35:599] AT+HTTPREAD␍␊
[23:51:35:628] ␍␊
[23:51:35:628] +HTTPREAD:290␍␊
[23:51:35:635] <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">␊
[23:51:35:692] <title>500 Internal Server Error</title>␊
[23:51:35:735] <h1>Internal Server Error</h1>␊
[23:51:35:766] <p>The server encountered an internal error and was unable to complete your request. Either the server is overloaded or there is an error in the application.</p>␊
[23:51:35:935] ␍␊
[23:51:35:935] OK␍␊
```
*ip addresses aren't real.*

My server received invalid request (with JSON body, but without special header), and replied `500 Internal Server Error`.

Revision: 1137B08SIM900M64_ST_DTMF_JD_MMS

title: Send JSON body with SIM900 board

Answers: 1

body:
Thanks for **@Majenko**.\
I solved problem by upgrade firmware to **1137B15SIM900M64_ST**.


body:
Ok here it goes, my first ever question posted to stackexchange! Please be gentle on me!

I am using an Arduino UNO (at the moment, will move to a faster micro later - but still use an Arduino sketch) to read in data as an SPI slave to extract the display data off of a commercial product that has no other exploitable data output that I can use. I am using a very generic sketch that Nick Gammon posted for the purpose of demonstrating the capability - and I can read the SPI data coming in ok. (Thanks Nick!)

The data is being pulled from a commercial product that has a 8 character, 5X7 dot matrix LED display that was specially made for this product and after exhaustive searches and emails to Broadcom/Avago - has no datasheet, but there are slightly similar products that I was able to use to get a bit of a handle on how the part works, I just went on the assumption that even if the interfaces are not the same, they probably didn't reinvent their command structure. However; the display doesn't have a nice driver chip embedded like your typical parallel LCD display.

I had to do a bit of reverse engineering using a logic analyzer to figure out:
1. It is SPI data at 4MHz.
1. The gist of the commands coming in and in what order
1. Used excel to convert the pixel mapping of the display to the font actually getting displayed on the device.
1. That the displayed font/text for each of the 8 characters is made up of 5 bytes - where the bit positions of those bites end up lighting a tiny LED in the display so the letter 'H' looks like 0x7F, 0x08, 0x08, 0x08, 0x7F. Each byte controls a column of 7 LEDs, ignoring a row.

Right now:
- I am using a modified version of Nick's slave sketch to simply extract the first 44 bytes of the command string to display something on the display
- all that is important to me is the 40 bytes after the first 4
- because those bytes are what get displayed. I am taking 5 elements of the 44 byte array that I know correspond to a character and spitting them out on the serial monitor such as:
   ```
   0x00, 0x01, 0x5F, 0x11, 0x00 // i
   0x7F, 0x08, 0x08, 0x08, 0x7F // H
   etc...
   ```

And now after a lengthy introduction - my actual question:

*I need to parse the patterns of each of the 5 bytes that makes up a letter and convert it to ASCII text so that the actual word is displayed on the serial monitor.*

Back when I used to use another programming language / environment on PICs we had things like LOOKUP and LOOKDOWN which made comparing patterns a bit more abstracted, which is weird considering Arduinos...

I need help coming up with a function that takes the 5 bytes that I need to build each letter from and maybe compares it to an array that represents each possible letter and then maybe passes the matching result to another function to build / concatenate the displayed word out of those characters? That method sounds wildly inefficient, but it's all my little brain can come up with and I'm drawing a blank on how to even do that... I don't need a lot of error checking because thus far the data I'm getting is spot on with what I see on the actual display - we are also talking one 8 character word (max) at a time and it is fairly static, no scrolling words or a lot of chatter - just a single word or some data that changes relatively infrequently. But the displayed data can be different enough than the last to make trying to match entire words out of the question unless it's a side feature to speed things up. I think work properly it needs to work on one character out of 8 - one at a time. Another thought is maybe summing the 5 bytes to determine if we have a match or not, but I'm not sure if two different characters might end up having the same sum? Math is not my strong suit. Thanks for any and all help.

title: Best strategy to parse 5 byte arrays to find a pattern

Answers: 1

body:
This is really a pure programming problem rather than an Arduino one, but to get you started, you could do a table lookup, like this:

<!-- language: lang-c++ -->

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

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

    unsigned char patterns [] [5] =
      {

        { 0x7F, 0x08, 0x08, 0x08, 0x7F },   // H

        // other byte patterns here

      };  // end of patterns

    char patterns_converted [] =
      {

      'H',

      // other letter equivalents here

      };  // end of patterns_converted

    char convert_pattern (unsigned char what [5])
      {
      for (int i = 0; i < ARRAY_SIZE (patterns_converted); i++)
        if (memcmp (what, patterns [i], 5) == 0)
          return patterns_converted [i];

      return '?';

      } // end of convert_pattern

    int main ()
    {

      unsigned char test1 [5] = { 0x7F, 0x08, 0x08, 0x08, 0x7F };
      unsigned char test2 [5] = { 0xAA, 0xBB, 0xCC, 0xDD, 0xEE };  // won't be found

      char x = convert_pattern (test1);

      printf ("Result for test1 is %c\n", x);

      x = convert_pattern (test2);

      printf ("Result for test2 is %c\n", x);

    }

You would find out all your bit patterns and put them in the patterns array, and then put the equivalent letter in the patterns_converted array.

The function convert_pattern does a linear search of the table of patterns, returning the corresponding letter, or "?" if not found.

I coded that in pure C++, but since the Arduino IDE basically uses C++ you should be able to convert it for your use.


body:
guys i am working on a rare project so i just need to ask some questions

I have a L298N H bridge motor driver, a Aduino uno board, 12v dc 4000rpm 2ampere motor and a 12v 7ah battery
I just want to ask can i use 12v 7ah battery with my L298N H bridge motor driver
please answer this project is very important to me
please help

title: can i use L298N H bridge with 12v 7AH battery?

Answers: 1

body:
Yes, though at 2A you're at the top end of the L298N current limit. Expect excessive heating. You will have to manage your thermal environment appropriately.

You should consider a more capable driver with more current headroom and less heat problems. (Note: the L298N is a very old chip and uses old technology. It's not a good choice for modern drive systems and a more appropriate device should be investigated, for example the MC33931 as the first hit on google).


body:
I'm trying to send NMEA 0183 sentences through LoRa.
Every dinstict NMEA message looks like several char arrays (sentences) followed by '\n'.
In the below picture we see one NMEA distinct message:

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

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

This message arrives in the Arduino input buffer every 1 second with differentiated values (numbers) and it has to be sent over LoRa as fast as possible.
In order to send it over LoRa I need to read all bytes on the input buffer and assign them to an array and send them as an array, not one by one. I know that Serial.read() reads only one byte, and that's the problem.
How can I read all bytes and send them as a whole?

This is my code:

      if (Serial.available()) {
         c = Serial.read();
         rf95.send((char *)c, sizeof(c));
         rf95.waitPacketSent();

I use RadioHead library, and the definition of **rf.95.send** is:
*RH_RF95::send (const uint8_t * data, uint8_t len)*

**c** is of char type.

title: What's the most direct way to assign Serial.read() bytes to an array?

Answers: 3

body:
All more complex Serial reading methods are based on `read()`.

Luckily there's a terminating character `'\n'` in your case, so you can implement something similar to `readBytesUntil` by yourself, if you want to.

body:
@DataFiddler suggested something like `readBytesUntil`.  In fact, you can just use `readBytesUntil`.  It returns either when timeout happens or when you reach the specified terminator.  It consumes, but does not include the terminator.  The timeout defaults to 1000 milliseconds, and can be modified with the `setTimeout()` method.

One downside is that you can't differentiate timeout, full buffer, and terminator reached.  This shouldn't be a problem except for serial transmission errors.
If your data is coming in at the NMEA standard 4800 baud, you could reasonably change the timeout to 5 milliseconds and still work.

<hr>

One thing that might bite you, is the line:
```
     rf95.send((char *)c, sizeof(c));
```
It is a mistake to cast the first parameter.  The error you got indicated you should write:
```
     rf95.send(&c, sizeof(c));
```
But the sizeof is also wrong.  The return type of `Serial::read()` is `int`, in part because there are 257 possible values.  If you declared c as an int, its size would be 2, not 1.

In any case, if you are using readBytesUntil, you pass the same buffer you passed it to rf95.send(), and the return value from the first as the second parameter of the second.

body:
I was missing a null termination character. That got me reading garbage from all over the buffer.
Adding a '0' at the end of the buffer's length is mandatory.
Plus, as David G. noticed, sizeof() function is incorrect. strlen() must be used.


body:
I needed to send MPU6050's accelerometer and gyroscope data and voice recognition module's voice command status flag through the HC-05 Bluetooth module to receiver Bluetooth and Arduino. But because both Bluetooth HC-05 and voice recognition module use software serials, and not more than one software serial can function at a time, I had to search for a solution. I found that one solution is to alternate the serials. But my project is a wireless head mouse project. So, to decrease the mouse cursor lag, I need HC-05 and voice recognition module V3.1 to work parallelly. So, I went to implement the Master/slave approach to use two Arduino boards (one for the collection and calculation of data from MPU and voice recognition module) and the other for just getting these values and sending this data through HC-05. But I got stuck right in the basics. I tried to send data between two interconnected Arduino Micros in Master/Slave manner which uses I2C protocols, but it didn't work. I got nothing on the serial monitor set to 9600 bauds and "Newline" selected on the slave board's Serial monitor. The code I used was from the Arduino examples itself.

Circuit connections between Arduino Micros:
A4->A4
A5-> A5
Gnd-> Gnd

These connections are from the Example tutorials on this website which I followed and double-checked.

I tried both Master Writer &Slave Receive, and also Master reader & Slave sender.

**Master Writer & Slave Receiver sketch respectively**

    // Wire Master Writer
    // by Nicholas Zambetti <http://www.zambetti.com>

    // Demonstrates use of the Wire library
    // Writes data to an I2C/TWI slave device
    // Refer to the "Wire Slave Receiver" example for use with this

    // Created 29 March 2006

    // This example code is in the public domain.

    #include <Wire.h>

    void setup()
    {
      Wire.begin(); // join i2c bus (address optional for master)
    }

    byte x = 0;

    void loop()
    {
      Wire.beginTransmission(4); // transmit to device #4
      Wire.write("x is ");        // sends five bytes
      Wire.write(x);              // sends one byte
      Wire.endTransmission();    // stop transmitting

      x++;
      delay(500);
    }

        // Wire Slave Receiver
    // by Nicholas Zambetti <http://www.zambetti.com>

    // Demonstrates use of the Wire library
    // Receives data as an I2C/TWI slave device
    // Refer to the "Wire Master Writer" example for use with this

    // Created 29 March 2006

    // This example code is in the public domain.

    #include <Wire.h>

    void setup()
    {
      Wire.begin(4);                // join i2c bus with address #4
      Wire.onReceive(receiveEvent); // register event
      Serial.begin(9600);           // start serial for output
    }

    void loop()
    {
      delay(100);
    }

    // function that executes whenever data is received from master
    // this function is registered as an event, see setup()
    void receiveEvent(int howMany)
    {
      while(1 < Wire.available()) // loop through all but the last
      {
        char c = Wire.read(); // receive byte as a character
        Serial.print(c);         // print the character
      }
      int x = Wire.read();    // receive byte as an integer
      Serial.println(x);         // print the integer
    }

**Master Reader & Slave Sender sketch respectively**

    // Wire Master Reader
    // by Nicholas Zambetti <http://www.zambetti.com>

    // Demonstrates use of the Wire library
    // Reads data from an I2C/TWI slave device
    // Refer to the "Wire Slave Sender" example for use with this

    // Created 29 March 2006

    // This example code is in the public domain.

    #include <Wire.h>

    void setup() {
      Wire.begin();        // join i2c bus (address optional for master)
      Serial.begin(9600);  // start serial for output
    }

    void loop() {
      Wire.requestFrom(8, 6);    // request 6 bytes from slave device #8

      while (Wire.available()) { // slave may send less than requested
        char c = Wire.read(); // receive a byte as character
        Serial.print(c);         // print the character
      }

      delay(500);
    }

    // Wire Slave Sender
    // by Nicholas Zambetti <http://www.zambetti.com>

    // Demonstrates use of the Wire library
    // Sends data as an I2C/TWI slave device
    // Refer to the "Wire Master Reader" example for use with this

    // Created 29 March 2006

    // This example code is in the public domain.

    #include <Wire.h>

    void setup() {
      Wire.begin(8);                // join i2c bus with address #8
      Wire.onRequest(requestEvent); // register event
    }

    void loop() {
      delay(100);
    }

    // function that executes whenever data is requested by master
    // this function is registered as an event, see setup()
    void requestEvent() {
      Wire.write("hello "); // respond with message of 6 bytes
      // as expected by master
    }

title: How to fix Master-Slave communication between Arduino Micros Not Working and no serial monitor output problem?

Answers: 0


body:
The idea is to connect more than 1 arduino slave to master as shown in schamatic

<!-- Begin schematic: In order to preserve an editable schematic, please
     don't edit this section directly.
     Click the "edit" link below the image in the preview instead. -->

![schematic](https://i.stack.imgur.com/WtU2Z.png)

<!-- End schematic -->
The problem is TX slave can not just combine to master RX.
It need to done some trick like tri-state buffer to make slave TX one at time.
Anyway, avr port can config as tristate buffer.
(Q1)Is there any software solution to done this?
Second If I connnect TX to RX for half-duplex communication (using 1 data line). How to make Rx stop listenning to its self while transmiting data?

title: How to connect more than one arduino serial port together

Answers: 4

body:
You can do it with two diodes and a resistor:

<!-- Begin schematic: In order to preserve an editable schematic, please
     don't edit this section directly.
     Click the "edit" link below the image in the preview instead. -->

![schematic](https://i.stack.imgur.com/YgEq7.png)

<!-- End schematic -->

You'll still have to implement some system to prevent collisions, but electrically that will be sound.

body:
You can use a single-pole dual throw switch. a simple switch that can switch lines between multiple slaves.

Limitation: The salve will not be able to create a request unless the master has selected its corresponding lines.
Master has to actively ask for the data or send commands to the slaves. Slaves may not be able to initiate the communication (when not selected)

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

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

body:
Update Nov. 2020: my answer below, though a bit insightful and with many correct statements, is wrong. My schematic below will indeed prevent the Arduinos from damaging each other, but it will not allow proper communication. [Majenko's answer here](https://arduino.stackexchange.com/a/77592/7727) is right. Use his schematic, but read my answer below as well for additional insight and ideas.

----

ORIGINAL ANSWER:

You can do it with 2 resistors, as shown below. That's it! Super simple!

## Electrical explanation:
The goal is simply to protect the two Tx pins from killing each other. Without the resistors one Slave might be writing output LOW while the other Slave is writing output HIGH, which is a **dead short**--damaging both devices. Simply putting a 1k resistor in series with each Tx pin like this prevents that dead short. Now, if one Tx pin is HIGH while the other is LOW, you get current flow from one into the other through a total of 2kOhms, which means the current will be only `I = V/R = 5V/2000 Ohms = 2.5mA`, which isn't a problem, as each pin can handle 40mA max and 20mA~30mA continuous safely. Also, a 1k resistor isn't much load, so you should still get good serial throughput even at fairly high baudrates.

<!-- Begin schematic: In order to preserve an editable schematic, please
     don't edit this section directly.
     Click the "edit" link below the image in the preview instead. -->

![schematic](https://i.stack.imgur.com/qelVr.png)

<!-- End schematic -->

# The code:
The communication code will be done as normal with `Serial.print()` or `Serial.write()`, `Serial.read()`, etc. Nothing special about the code, except you should make an effort to keep the slaves from talking at the same time to prevent data corruption from slave to master. So, you should have Master *request* data from a Slave, and a Slave should only talk when it knows the other Slave is not talking (ex: it should only talk when spoken to). The Master coordinates the communication. In this way, this is like SPI: the Master is in charge and tells each Slave when to talk. Since both Slaves are always listening, just use an "ID" to indicate which slave is being spoken to. If a Slave doesn't see it's ID, it should ignore the message.

Ex:

Request a new temperature reading from Slave 1:

    Serial.println("1:T");

Now, wait until you get the full response from Slave 1, then send out a request for...let's say, some current reading, from Slave 2:

    Serial.println("2:C");

The exact communication codes are up to you--your imagination is the limit.

Again, both slaves see both messages, but they look at the number at the beginning and only reply if it's their number. Doing this technique, you could connect nearly infinite Slaves all on the same line, just adding a 1k resistor to each Slave's Tx line before the junction where they all connect back to the Master's Rx line.

Pretty cool. I never thought of doing this before until you asked the question. Good question.

body:
For this scheme to work, you need to make sure that at most one slave
drives its TX at any given time. You will have to devise some protocol
by which the master addresses one slave, and then only that slave
responds. The problem is:

* both slaves must have their serial ports turned on in order to notice
  when they are addressed by the master
* an active serial port keeps its TX pin in a low impedance state,
  actively driving it HIGH when not transmitting data.

The best way out of this dilemma is to modify the hardware, as per
Majenko’s answer. If, for whatever reason, you cannot do that
modification, there may be a software-only solution, but only if the
underlying hardware allows you to turn off the serial transmitters of
the slaves, while keeping the serial receivers active.

The Arduino API dos not allow you to keep the serial transmitter active
while the receiver is disabled: the functions `Serial.begin()` and
`Serial.end()` control the transmitter and the receiver as a whole. You
may be able to do that by accessing the hardware at a lower-level. You
didn't state what kind of Arduino you are using. Assuming you have
something similar to an Uno, you can disable the transmitter with:

```cpp
UCSR0B &= ~_BV(TXEN0);
```

and enable it again with:

```cpp
UCSR0B |= _BV(TXEN0);
```

If you want to use the Arduino API for serial communication, you will
have to disable the transmitter right after `Serial.begin()`:

```cpp
const uint8_t TX_PIN = 1;

void setup() {
    pinMode(TX_PIN, INPUT_PULLUP);  // valid when transmitter is off
    Serial.begin(9600);             // enable serial port
    UCSR0B &= ~_BV(TXEN0);          // disable transmitter
}
```

But beware that then it will be enabled for a sort time (no more than a
few microseconds), right before you disable it. This may cause a short
if one slave boots while the other is transmitting data.

One problem with this kind of software-only solution is that bugs do
happen, and with your circuit, a bug in the protocol handling can burn
your hardware. If you can manage to at least add some protective
resistors, as in Gabriel Staples’ answer, that should keep you safe.


body:
I have to read out the teperature and humidity of four independent SHT31 sensors with the help of an ESP32. Is there any prefered way to do this, since the only examples I can find online are only with one sensor. I have no access to the address pins of the sensors.

Thank you in advance for any help!

title: Four temperature SHT31 sensors on ESP32

Answers: 2

body:
Yes, reading 4 SHT31 is possible with an ESP32.

If you have the analog version, readout is quite trivial: you simply use 8 analog inputs (2 for each) to read the signal.

If you have the digital version, which has an I2C interface, you need to control each sensor's address pin separately to select the specific sensor you want to read. Otherwise, there will be an address collision on the bus.

body:
Try using TS3A5018, part from TI.
You can then connect 4 independent I2C devices (SHT31).

There are also dedicated I2C channel multiplexers such as these. ![enter image description here](https://i.stack.imgur.com/dzics.jpg)

Below is the example for I2C multiplexer from TI

![enter image description here](https://i.stack.imgur.com/Qf2vl.jpg)


body:
saw somewhere that in order to upload a hex file to an arduino you can look at the Arduino IDE - see the command it runs, then replace the hex file with your file.
this is the command I see in the output window:

```C:\Program Files\WindowsApps\ArduinoLLC.ArduinoIDE_1.8.42.0_x86__mdqgnx93n4wtt\hardware\tools\avr/bin/avrdude -CC:\Program Files\WindowsApps\ArduinoLLC.ArduinoIDE_1.8.42.0_x86__mdqgnx93n4wtt\hardware\tools\avr/etc/avrdude.conf -v -patmega328p -carduino -PCOM5 -b115200 -D -Uflash:w:C:\Users\yossi\AppData\Local\Temp\arduino_build_696128/sketch_aug21a.ino.hex:i ```

I try running this from command (as admin):
```
cd "C:\Program Files\WindowsApps\ArduinoLLC.ArduinoIDE_1.8.42.0_x86__mdqgnx93n4wtt\hardware\tools\avr\bin"
avrdude -CC:\Program Files\WindowsApps\ArduinoLLC.ArduinoIDE_1.8.42.0_x86__mdqgnx93n4wtt\hardware\tools\avr/etc/avrdude.conf -v -patmega328p -carduino -PCOM5 -b115200 -D -Uflash:w:C:\Users\foosMaster\AppData\Local\Temp\arduino_build_696128/sketch_aug21a.ino.hex:i
```
gives me ```Access is denied.```
in fact, just running ```avrdude``` gives the same error, so really - this has nothing to do with the COM port (which works fine from the IDE)
I tried closing the IDE and running again, tried rebooting - the same.

*** edit 1 ****

I actually ran this:

    cd "C:\PROGRA~1\WindowsApps\ArduinoLLC.ArduinoIDE_1.8.42.0_x86__mdqgnx93n4wtt\hardware\tools\avr\bin"
    avrdude -CC:\PROGRA~1\WindowsApps\ArduinoLLC.ArduinoIDE_1.8.42.0_x86__mdqgnx93n4wtt\hardware\tools\avr/etc/avrdude.conf -v -patmega328p -carduino -PCOM5 -b115200 -D -Uflash:w:C:\Users\foosMaster\AppData\Local\Temp\arduino_build_696128/sketch_aug21a.ino.hex:i

since I didn't want to mess with wrapping the params - but I don't really think it matters - as the problem is running avrdude without any parameter still gives me the same error: ```Access is denied.```

title: Windows upload from command line gives Access Denied

Answers: 1

body:
This is because you are running the Windows App Store version of the IDE.

Windows doesn't like you messing with the insides of App Store programs (I think it scares it...).

Install the *real* version of the IDE from the Arduino.cc website and it will work.


body: I'm working on a project that involves stepper motors, and I'm mainly using DRV8825 stepper drivers. At the moment, it seems like only one of my drivers actually gives the motors any current. The others usually return 0s when I measure their VREFs. One returns a value but still can't pull the motors. After checking all of my DRV8825s and finding only two returned VREFs, I checked my A4988s and none of them gave anything (aside from power supply voltage when measuring different pins). Is there a way I can figure out whether my stepper drivers are actually fried? I have a suspicion that maybe the potentiometers on the drivers are thrown off or there's some other issue I can't place. I'm happy to give more information if that can help to figure out what's going on here. Thank you!

title: Is there a method of figuring out whether or not my stepper drivers are dead?

Answers: 1

body:
Most surefire way to tell if your drivers work is to wire them up CORRECTLY and try them out.  You should not be frying them if you have the correct setup (including current limit) for your conditions.  That said, conditions include your heat sink install and the environmental temperature.

The usual gotchas:

 - Note that DRV8825 and A4988s may have different pin locations so be sure to orient them correctly (check their EN pin location) if using a shield.
 - Also note that the gains from the voltage to the current limits will be different for the different model #s.  Be sure to use an appropriately sized screw driver and attach the meter to the screw driver as you turn to adjust the current limit.


body:
I'm a bit stumped on how to switch on a solenoid using a transistor using my Arduino Nano's 5v Output. The solenoid runs on 12V, so I used an NPN transistor to connect the 12V source to the solenoid whenever Arduino sends current to the transistor's base. I connected all the grounds together to the Nano's ground pin, but the solenoid still doesn't switch.

I know the transistor works properly, because the solenoid switches when I use the battery to send base current instead of the Nano. I would think the Nano is capable of sending enough current to activate the Collector -> Emitter path but might be wrong. I'm also wondering if it's an issue with grounding the circuit, but I've made sure there is a common ground. What do you think I'm doing wrong? BTW the transistor I am using is D882P. I would appreciate any help.

<!-- Begin schematic: In order to preserve an editable schematic, please
     don't edit this section directly.
     Click the "edit" link below the image in the preview instead. -->

![schematic](https://i.stack.imgur.com/KeaJW.png)

<!-- End schematic -->

title: Switching a Solenoid Using Arduino's 5V Output?

Answers: 1

body:
## Low-side switching an inductive load (such as a relay) using a microcontroller (such as Arduino), NPN BJT transistor (with full base resistor calculations), and snubber/flyback diode

_Note: this answer demonstrates using the 2N3904 NPN transistor for all of the calculations, since that's what's in the schematic in the question. However, after writing the answer, I noticed the words at the end of the question state it is a D882P (also an NPN type) transistor. So, just follow my methodology here but use the appropriate values for your NPN transistor type, which you can obtain from the datasheet. A quick [Google search for "d882p datasheet"][1] reveals [this as a potential datasheet][2]._

2N3904 is an NPN transistor ([datasheet](https://www.onsemi.com/pub/Collateral/2N3903-D.PDF)), as opposed to a PNP transistor, so it must be connected directly to GND and switch the low side of the circuit only, so wire it like this instead:

![schematic](https://i.stack.imgur.com/I7mhC.png)

Notice I've added a diode, D1, to dissipate inductance-induced voltage spikes created when electromagnetic fields (a form of energy storage) collapse in the inductor each time you turn the switch OFF. This diode, due to its *function* (not type), is called a ["flyback", "snubber", or "clamp" diode][3]. Again, it protects the transistor and other components from inductance-induced voltage spikes from the relay coil/inductor. When a voltage spike occurs, it will simply travel around that loop through the diode, relay, and resistor R2 again and again and again until it has all been dissipated as heat in those components and there is no more voltage spike remaining.

I've also added a resistor R2 to limit current through the relay coil. You'll have to size this appropriately to get the correct current through your relay coil, based on the relay's datasheet. If your relay's datasheet says to hook up the relay to 12V directly, you can remove this resistor.

And you'll definitely need a base resistor (R1 in my circuit) or else you'll burn up your Arduino pin.

## First, let's collect some necessary values from the [Datasheet][4]. These will be used in the calculations below:
1. **VBE(sat)** = 0.65 to 0.95V.
    1. This is the diodic voltage drop from Base to Emitter when the transistor is "saturated", or fully ON.
1. **hFE_min** = 30
    1. Notice in the screenshots below that I have crossed out all of the 2N3903 transistor hFE entries so they don't distract us from the 2N3904 entries, which is the transistor type I'm using for this example. I then chose the *lowest* hFE entry for this transistor, which is 30.
    1. This is the "guaranteed" minimum, or worst-case, DC current gain. The formula is simply: `I_max_permitted_from_Collector_to_Emitter = gain * I_Base_to_Emitter`. So, if your gain is 30, for example, and you drive a base current of 5mA from Base to Emitter, then the "guaranteed" maximum **_possible_** current allowed from the Collector to the Emitter will be `30 gain * 5mA = 150mA`. Again, this is not what you *will* get into the Collector, this is what you *could* get before the transistor itself starts limiting the current into the Collector rather than your load limiting the current through the Collector.
1. **Ic_max_continuous** = 200mA
    1. This is the max continuous current you can get from Collector to Emitter without overheating the transistor (assuming, I think, you have adequate cooling through conduction and possibly even convection and radiation via heat sinks--I need to brush up on the thermal and power equations myself). The datasheet may specify if a heat sink is required to achieve this current, but regardless, you should keep your continuous current down to about half this value or less if possible, as the device may reach crazy high temperatures of like 150 C or something with this current and no convective cooling or heat sink. For short bursts, hitting this current is just fine.

Here are some screenshots of where to find these values in the datasheet:

[![enter image description here][5]][5]

Notice in this next image I've crossed out all of the 2N3903 hFE lines so they don't distract us from the 2N3904 entries, which are for the transistor we care about in this example. Choose the lowest hFE value as the gain you will use in your estimates in order to have a "conservative" estimate, virtually guaranteed to fully turn on your transistor in all cases (ie: for all Collector current values you might like to switch on and off).

[![enter image description here][6]][6]

## Now, let's calculate a Base resistor value for an NPN BJT transistor, assuming your goal is to _fully turn on_ (saturate the Base-Emitter channel of) the transistor:

VBE(sat) has a diodic voltage drop of **0.65 to 0.95V**, so your resistor would have to burn off `5 - 0.95 = 4.05V` to `5 - 0.65 = 4.35V`. Let's just use the lower 4.05V value so we will size for higher currents and faster turn-on speeds.

Your minimum hFE (gain) value for the 2N3904 transistor (not the 2N3903) is **30**. Maximum continuous Collector current, Ic is **200mA**, so let's **increase that by a factor of 2 to 4** and size for `200mA * 3 = 600mA` to 1) more fully saturate the Base to Emitter channel and get closer to full turn on under all cases, 2) get faster turn-on, and 3) overcome the fact that decreased gain occurs at higher Collector currents. In **Figure 15. DC Current Gain**, from the datasheet, for instance, shown below, it shows that the normalized gain decreases from ~0.28 at 100mA Collector current to ~0.13 at 200mA Collector current, which means that the gain of 30 found in the datasheet at 100mA Collector current indicates the gain at 200mA Collector current will actually be approximately `30 gain/(0.28/0.13) = 13.9 gain`. Simply multiplying the Collector current we are sizing for by a factor of 2 to 4 (3 in our case) accounts for this fact, so we will use 600mA instead of 200mA in our maximum Collector current calculations below.

[![enter image description here][7]][7]

So, `600mA / 30 gain = 20mA` Base to Emitter to get rock solid turn-on performance. Arduino can do up to **40mA** per pin so this is Ok. Note that I recommend **30mA** max per Arduino pin (for the ATmega328 microcontroller), and there is also a _combined output limit_ for the ATmega328 microcontroller of _**200mA** for all pins combined_, which you should keep in mind. I describe this on my website in my article ["Arduino Power, Current, and Voltage Limitations" here][8].

`V = IR`, so `R = V/I`, so resistor, R that we need `= 4.05V/0.020A = 202.5 Ohms`. This is the minimum recommended base resistor size. Don't go too much smaller than **200 Ohms**, if you go smaller than that at all. A 100 Ohm resistor, for instance, would allow a maximum base current of `I = V/R =` (I intentionally use the higher voltage value here) `4.35V/100 Ohms = 43.5mA`, which could damage your pin.

Don't go larger than **600 Ohms** or else you risk not turning on the transistor fully by not saturating the Base to Emitter channel. A 600 Ohm resistor would give you a guaranteed max Base to Emitter current of `I = V/R =` (I intentionally use the smaller voltage value here) `4.05V/600 Ohms = 6.75mA`, which with a gain of 30 would give you a max Collector current (based on your relay coil resistance now) of `6.75mA * 30 gain = 202.5 mA`. However, as indicated from Figure 15 shown above, a more realistic gain at 200mA Collector current might be only 13.9, which means your maximum allowed Collector current with a 600 Ohm resistor would be `6.75mA * 13.9 gain = 93.8mA`. But, at this current your gain would actually be > 30, not 13.9, which leads back to the 200mA Collector current number. You can see this is a juggling game of numbers since the gain is NOT constant NOR linear, but rather is a function of Collector current, as shown by Figure 15 above. So, perhaps your actual maximum allowed Collector current with a resistor of 600 Ohms would be more like 130mA or something. The point is: any larger of a base resistor than 600 Ohms and you most likely won't be able to achieve the transistor's rated maximum continuous Collector current even if you wanted to. **So, there's a reasonable R value range!: 200 Ohms to 600 Ohms,** perhaps even leaning more towards the 200 Ohms side if you expect to have high momentary Collector currents anywhere near your maximum continuous Collector current rating of 200mA.

---------

## Additional notes on high-side vs low-side driving with NPN BJT or N-Channel MOSFET transistors, for clarity:

An NPN transistor can switch high-side voltages too--you just have to drive the necessary Base to Emitter current is all (and don't exceed any maximum ratings)! That's it! So...if you try to drive the high side, think about it: you turn it on with 5V so your voltage from Collector to GND can't exceed ~5V now because as current starts to flow through the collector, voltage would come up on the Emitter side until your base current no longer flows. Your system would be fighting itself. Even if you gave it 12V before the Collector you'd never see more than ~5V at the Emitter, assuming your Base drive voltage was 5V. If you can design around it, go for it, but generally the "easy" or "normal" way to do things is to use NPN to switch low-side voltages and PNP to switch high-side voltages.

The same goes for N-channel and P-channel MOSFETS. Use N-channel to switch low-side voltages and P-channel to switch high-side voltages, UNLESS you are doing some fancy driving (again), of N-channel to switch high-side voltages, as N-channel MOSFETs are more efficient and can switch higher currents than their equivalent P-channel pairs, due to some electron hardware mumbo jumbo stuff.

Keywords: transistor sizing; BJT transistor circuit calculations, equations, and datasheet; arduino and electrical engineering: transistor (BJT) sizing, equations, datasheet, and calculations example

## Additional reading:
1. [my answer] [Electronics Stack Exchange: When is a MOSFET more appropriate as a switch than a BJT? [and a BJT more appropriate than a MOSFET]](https://electronics.stackexchange.com/questions/13079/when-is-a-mosfet-more-appropriate-as-a-switch-than-a-bjt/527268#527268)

  [1]: https://www.google.com/search?q=d882p datasheet&oq=d882p datasheet&aqs=chrome..69i57j69i59j69i60.210j0j7&sourceid=chrome&ie=UTF-8
  [2]: https://www.st.com/resource/en/datasheet/2sd882.pdf
  [3]: https://en.wikipedia.org/wiki/Flyback_diode
  [4]: https://www.onsemi.com/pub/Collateral/2N3903-D.PDF
  [5]: https://i.stack.imgur.com/YSKUO.png
  [6]: https://i.stack.imgur.com/31x6p.png
  [7]: https://i.stack.imgur.com/lMY8F.png
  [8]: https://www.electricrcaircraftguy.com/2014/02/arduino-power-current-and-voltage.html


body:
I got this neo 6m gps module from a broken drone. and i would like to connect it to nodemcu v3 board.
most of the gps module that i have seen are with 4 pins (vcc,gnd,tx,rx) , but this module has 6 pins (gnd,vcc,txd,rxd,scl,sda) .

i am not sure how to wire it up and what library to use.

![Neo 6](https://i.stack.imgur.com/EVVCf.jpg)
![NodeMcu v3](https://i.stack.imgur.com/6G21M.jpg)

title: How to connect neo 6m 6pin module with nodemcu v3

Answers: 2

body:
The 4 pins VCC/GND/TX/RX are the same as any other GPS module.

The other two pins, SCL and SDA, are nothing to do with the GPS. They connect to the HMC5883L compass chip.

Use the normal TinyGPS library for the GPS, and a HMC5883L library (such as [this one](https://github.com/jarzebski/Arduino-HMC5883L)) for the compass.

body: Rx and tx pin are for UART communication and SCL and SDA are for I2C communication. Most common gps module use UART communication method .... You can go with UART too this will help you to choose better  library option. Most library file are coded for UART method.  I recommend you to use vcc , gnd ,rx and tx pin. Escape scl and sda pins.


body:
I have an Arduino Nano Every device that seems to have shorted out.

I use a lighted USB hub with buttons that turn connections on and off.  Each button has its own LED that indicates power state for its associated port.

Anyway, when I plug my Arduino Nano Every into that USB hub, the lighted buttons turn off for half of the hub, like the Arduino is shorting out the hub.

I use a different Arduino and have no problems, so it's definitely the Arduino.

Any idea what could have caused this?  I was using the Arduino with a TMUX1511 switch chip and using pins  D9-D12 to turn on and off the 4 internal switches in the chip.  It's using very low voltage (5v) and amperage is (25 mA).  I used the 5v and gnd pins on the Arduino to power the TMUX1511 chip, but with such low amperage, I can't see how that could have caused the Arduino to fry.

Any ideas?

title: Do Arduino Nano Every devices short out?

Answers: 1

body: this might because of powering issue...try using different source having a good number of current capability. likely up


body:
First off, I should note that I'm not sure what tags best apply here, and I can't seem to find any that relate to schedulers, etc. Please inform me if they are not the right ones.

I have a simple, portable task scheduler (it only relies on millis(), and runs on different Arduino-supported systems) that is called via a function in loop() and that picks and then runs a function pointer (the "task") from a list of tasks with status, sleep, and priority information.

I would like to have a way to determine and to tell the user how much CPU time is being spent on running tasks vs. being idle.

The problem is that there can be other functions being called from loop(), not just my scheduler. It would thus be a bad idea to track total time vs. time spent in a task. If I did, the CPU use would always read low, since the actual task time cannot use all of the CPU time since the other tasks in loop() would be quietly using some of it.

However, if I specifically track time in the scheduler vs. time spent in task, I run into a new issue. I would use more memory (a few more bytes, but I'm using a lot already...) and more CPU*, since I'd have to keep track of the total so far *and* also the current runtime for that iteration of the scheduler. That's on top of the similar construct determining the runtime of the task. Mainly, though, the issue is that the loop() function and scheduler run fast enough that the millis() timer can tick slower than the changeover between my scheduler and the loop() function. This causes the timing to also be off, since it would be counted if it ticks in the scheduler even if it was mainly loop()'s fault.

Is there a general methodology for computing the CPU time? It would be difficult to time-slice the scheduler, and that would run slower anyway. I could count the proportion of scheduler calls that run/don't run tasks, but that won't work because tasks take longer than the no-op that happens if a task doesn't run, and it makes no accounting for task length.

*On an AVR system, the 8-bit CPU uses a surprising aggregate time on all those 32-bit operations, between the sleep time calculations (on sleeping tasks only, to be fair) and the elapsed time calculations that fed into my prior CPU use attempt. It wasn't the only cause, but I saw quite a bit of timing slip on one attempt of coding the scheduler because of a similar issue.

title: Estimating CPU load of a task scheduler

Answers: 2

body:
The only metric you have is time. The only thing you can do is compare that time over iterations / task calls. The typical approach is to note the time at the start of a task "tick", and note it at the end. Then add the difference to the total for that task.

When you want to then look at usage percentages you can compare those totals to the total time the system has been running.

The total runtime is already done for you, in the form of `millis()`, so you don't need to worry about that.

Recording each task's total runtime in microseconds is simple enough, but of course will entail an overhead. That is unavoidable no matter what strategy you take. It's kind of quantum: the act of measuring changes the results.

If you treat your "idle" task the same as any other task (which is the normal way of doing things - the idle task is just a task that does nothing) then the sum of all the time counts for all the tasks = (within a certain granularity) the total amount of time your task scheduler has been running. The difference between that and the system runtime (`millis()`) is the proportion of the time your scheduler has been running compared to other things happening in `loop()`.

Whether you compare to `millis()` or `micros()` for the system runtime is up to you. By storing `micros()` per task you're getting a reasonable resolution for each tasks's runtime (but with a limit to how long before it wraps - but you can handle that in software by carrying over to another lower resolution counter if you want), but you can then discard some of that resolution when doing your calculations if you don't need it at the time.

Estimating runtime in a co-operative multitasking system like this is never good, and often not bothered with because of that. It's always a guestimate with the results being skewed by the measuring, since the measuring is synchronous with the execution of the tasks.

In a proper context-switching multitasking system you would normally operate on the number of "ticks" of the system rather on time. That is, simply count 1 each time a task is switched in by the context switcher. Since each task has a fixed runtime controlled by the granularity of the scheduler it's then trivial to know that task X has been running for X/TOTAL_TICKS % of the time. Any calculations will be themselves done in a task - maybe the idle task, or a system accounting task.

body:
The cheapest (in every sense) way I know to display "idleness" is to set an output pin when you enter the scheduler and clear it again when you dispatch a task (other than your idle task, if there is one). Or reverse this, if you want to display load instead. These can be accomplished with a single instruction each. Low impact on your memory, execution time, assembly time, and wallet.

How precisely do you want to report this?

 - An LED on the output will fade and brighten according to the load. If you need damping (perhaps the load is brief and "peak-y") add an R-C filter to the LED circuit.

 - Connect a DVM, or even better, a mechanical VOM if you can find one, to the output and read load from the meter. A mechanical meter would do some damping for you. A DVM will probably need the filter from the previous suggestion.

- Loop the filtered output back into an analog input and read the load to a precision of ~ 0.1%! That's way more significance than is justified so round it as you see fit.


body:
I'm trying to do a small test where I am using the ISR on the Arduino Pro Micro it up from sleep mode. I'm using a Force Sense Resistor (FSR, a resistor that changes it's resistance depending on how hard you press it) with a voltage divider circuit with the output of the voltage divider connected to an analog pin and the digital interrupt pin. I'm not able to get the interrupt to trigger no matter what condition I have. I don't believe the Vout on the voltage divider is too low since the ADC registers values between 0 to 1000 (0V to about 4.8V) when the FSR is pressed. Is there anything wrong with my code that is preventing my test from working properly?

    uint8_t LED = 9;
    uint8_t wakeup = 2;
    uint8_t enable = 0;

    void Wakeup(void);

    void setup() {
      // put your setup code here, to run once:
      pinMode(LED, OUTPUT);
      pinMode(wakeup, INPUT);
      attachInterrupt(digitalPinToInterrupt(1), Wakeup, RISING);
      Serial.begin(115200);
    }

    void loop() {
      // put your main code here, to run repeatedly:
      //Serial.println(analogRead(A2));
      if (enable == HIGH)
        digitalWrite(LED, HIGH);
      else if (enable == LOW)
        digitalWrite(LED, LOW);
      if (analogRead(A2) < 700)
        enable = 0;
    }

    void Wakeup(void) {
      enable = 1;
      Serial.println("Interrupt");
    }

title: ISR Issue: Arduino Pro Micro

Answers: 1

body:
* Don't do serial prints inside an ISR.

* Your variable `enable` should be declared `volatile` as it changes inside an ISR. The compiler is entitled to cache the variable value if you don't do that.

* You are inconsistent in your use of `enable`. You test for LOW or HIGH but set it to 0 or 1. Now they happen to be the same, but someone might wonder. If you are going to test for LOW or HIGH, then assign LOW or HIGH to it.

See my reference question [How do interrupts work on the Arduino Uno and similar boards?](https://arduino.stackexchange.com/questions/30968/how-do-interrupts-work-on-the-arduino-uno-and-similar-boards/).

> I thought 0 and 1 were serial pins. I'm using digital pin 2

Not in the code you are not:

    attachInterrupt(digitalPinToInterrupt(1), Wakeup, RISING);

Do you mean:

    attachInterrupt(digitalPinToInterrupt(wakeup), Wakeup, RISING);

It's kind of confusing to have two names which differ only in case.


body:
I am currently learning Arduino Bluetooth connectivity with a HM-10S module.
I did some sample tutorial code and it works only with LightBlue app.

However, when I use the default Bluetooth pairing function from the android phone(samsung S10 plus), it seems failed to pair or connect.

So here is the cases I tried:

**Android App(LightBlue and also Arduino Bluetooth Controller) :**

Success connection without entering password.

**Windows 10 PC:**

Success pairing only by entering password: "123456", but no com port added

**Android phone(S10 plus) Default pairing method from setting**

Entered "123456" as password to pair, then no response.

So, what puzzles me is:
1. I can connect with some apps and do my work, without pairing using Android's setting utility; Is that implies establishing a connection for further action does not necessary to firstly getting things paired?

2. There are no com port installed after I paired the bt module, so it probably mean the module does not provide my desired feature. If that's the case, which BT module is recommended?

Great thanks if somebody could give me some ideas.

title: Cannot pair HM10 BLE 4.0 module from Android phone

Answers: 0


body:
I've been trying to create SMS alarm using Twilio, Firebase and Arduino IDE. Using sensors I am measuring the temperature. If the temperature is higher than a specified value (ESP reads that value from Firebase Realtime Database), a SMS should be sent using twilio. I am also storing the measures in Firebase Realtime Database. The code worked well, until I tried to add the part where it also pushed measurements (temperatures) to Firebase Realtime Database. It even prints in serial that it is connecting to Twilio api, however, I never receive the message.

Here's my code:

```
#/*
 * Twilio SMS and MMS on ESP8266 Example.
 */
 #include "FirebaseArduino.h"
#include "OneWire.h"
#include "DallasTemperature.h"
#include <ESP8266WiFi.h>
#include <WiFiClientSecure.h>
#include <ESP8266WebServer.h>
#include <sstream>
#include <iostream>
#include "twilio.hpp"

// Use software serial for debugging?
#define USE_SOFTWARE_SERIAL 0

// Print debug messages over serial?
#define USE_SERIAL 1

// Your network SSID and password
const char* ssid="SSID";
const char* password = "PASSWORD";

// Find the api.twilio.com SHA1 fingerprint, this one was valid as
// of July 2020. This will change, please see
// https://www.twilio.com/docs/sms/tutorials/how-to-send-sms-messages-esp8266-cpp
// to see how to update the fingerprint.
const char fingerprint[] = "BC B0 1A 32 80 5D E6 E4 A2 29 66 2B 08 C8 E0 4C 45 29 3F D0";

// Twilio account specific details, from https://twilio.com/console
// Please see the article:
// https://www.twilio.com/docs/guides/receive-and-reply-sms-and-mms-messages-esp8266-c-and-ngrok

// If this device is deployed in the field you should only deploy a revocable
// key. This code is only suitable for prototyping or if you retain physical
// control of the installation.
const char* account_sid = "SID";
const char* auth_token = "TOKEN";

// Details for the SMS we'll send with Twilio.  Should be a number you own
// (check the console, link above).
String to_number    = "+55555";
String from_number = "+66666";
String message_body    = "Hello from Twilio and the ESP8266!";

// The 'authorized number' to text the ESP8266 for our example
String master_number    = "+55555";

// Optional - a url to an image.  See 'MediaUrl' here:
// https://www.twilio.com/docs/api/rest/sending-messages
String media_url = "";

// Global twilio objects
Twilio *twilio;
ESP8266WebServer twilio_server(8000);

//  Optional software serial debugging
#if USE_SOFTWARE_SERIAL == 1
#include <SoftwareSerial.h>
// You'll need to set pin numbers to match your setup if you
// do use Software Serial
extern SoftwareSerial swSer(14, 4, false, 256);
#else
#define swSer Serial
#endif

String b;
int c;
#define FIREBASE_HOST "firebaseio.com"
#define FIREBASE_AUTH ""

#define ONE_WIRE_BUS 4
/********************************************************************/
// Setup a oneWire instance to communicate with any OneWire devices
// (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);
/********************************************************************/
// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);

float temp1 = 0;

/*
 * Setup function for ESP8266 Twilio Example.
 *
 * Here we connect to a friendly wireless network, set the time, instantiate
 * our twilio object, optionally set up software serial, then send a SMS
 * or MMS message.
 */
void setup() {
        WiFi.begin(ssid, password);
        twilio = new Twilio(account_sid, auth_token, fingerprint);

        #if USE_SERIAL == 1
        swSer.begin(115200);
        while (WiFi.status() != WL_CONNECTED) {
                delay(1000);
                swSer.print(".");
        }
        swSer.println("");
        swSer.println("Connected to WiFi, IP address: ");
        swSer.println(WiFi.localIP());
        #else
        while (WiFi.status() != WL_CONNECTED) delay(1000);
        #endif

        // Response will be filled with connection info and Twilio API responses
        // from this initial SMS send.

        twilio_server.begin();

        // Use LED_BUILTIN to find the LED pin and set the GPIO to output
        pinMode(LED_BUILTIN, OUTPUT);

         sensors.begin();
         Firebase.begin(FIREBASE_HOST, FIREBASE_AUTH);

}

/*
 *  In our main loop, we listen for connections from Twilio in handleClient().
 */
void loop() {
  b = Firebase.getString("002/alarm");
  c = b.toInt();
  Serial.print(c);

   sensors.requestTemperatures();
   temp1 = sensors.getTempCByIndex(0);
   StaticJsonBuffer<256> jsonBuffer;
JsonObject& timeStampObject = jsonBuffer.createObject();
timeStampObject[".sv"] = "timestamp";

JsonObject& root = jsonBuffer.createObject();
JsonArray& timestamp = root.createNestedArray("timestamp");
timestamp.add(timeStampObject);
JsonArray& temperature = root.createNestedArray("temperature");
temperature.add(temp1);

Firebase.push("Sensors/001", root);
   if (temp1 > c) {
        String response;
        bool success = twilio->send_message(
                to_number,
                from_number,
                message_body,
                response,
                media_url
        );
   }

          delay(20000);
}
```

Thanks in advance!

title: ESP8266, Twilio doesn't send SMS

Answers: 0


body: I'm using two (nrf24L01 + Arduino Uno) nodes to communicate with each other. Serial input from node1 will be sent to node2. A special character 'p' when sent to node2, it will reply that it's available. It is working fine when using arduino ide serial monitor on pc. When I use serial usb app on android to get serial input only the text is sent to another node and the special character sent does nothing and prints like any other message.

title: Problem with serial input from android serial usb app

Answers: 1

body:
I solved this problem by turning off CR+LF and selecting None for newline in send section. CR+LF was adding something extra to my input. By removing that program works fine with Android.

About CR,LF :
"Newline is a control character or sequence of control characters in a character encoding specification that is used to signify the end of a line of text and the start of a new one. Some text editors set this special character when pressing the ↵ Enter key." - (Wikipedia)


body:
I'm an absolute beginner, and lately I had some problem with this program I was trying to do.
Basically I wanted with the Arduino to count 3 pulses from an oscillator and store the time  of these 3 pulses, but as I said I am a beginner so I have no Idea on how to do it, I would appreciate your help.

title: Counter program

Answers: 2

body:
Simple code
```
int pin = 7;
unsigned long duration;

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

void loop() {
long duration = pulseIn(pin, HIGH);
 Serial.println(duration);
//delay(100);
}
```
Assuming that you are mentioning a squrewave this code mesures the time that squrewave pulse stays in `HIGH` and prints out in computer serial monitor.

You should send the signal to digital pin 7 (or put any pin you won't modify code `int pin = 7;`) 5 V HIGH and 0 V LOW.

The time unit measuring in here is in microseconds.
If you won't to measure low then `pulseIn(pin, LOW);`

**I took the example from Arduino official site you can refer more here**

https://www.arduino.cc/reference/en/language/functions/advanced-io/pulsein/

Remember this is the basic example there are other good methods than this...

Analog wave is bit too complex.

body:
While this is likely to need tweaks for your needs, it should get you looking at the right things - millis, interrupts, etc.
Official references at:
https://www.arduino.cc/reference/en/language/functions/external-interrupts/attachinterrupt/
https://www.arduino.cc/reference/en/language/functions/time/millis/

~~~

#define pulsesToStore 3
#define interruptPin 2
volatile unsigned char index;
unsigned long storedTimes[pulsesToStore];

void restartStorage() {
 index = 0;
 attachInterrupt(digitalPinToInterrupt(interruptPin), storeTime, RISING);
}

void storeTime() {
 storedTimes[index] = millis();
 index = index + 1;
 if(index >= pulsesToStore) { //stop storage
  detachInterrupt(digitalPinToInterrupt(interruptPin));
 }
}

void setup() {
 pinMode(interruptPin, INPUT_PULLUP);
 restartStorage();
}

void loop() {
  // does nothing for now.  this is where you would do something with the stored pulses, print to serial, etc.
}

~~~


body: I have seen a lot tutorials on L298N motor driver with nodemcu and ESP 32, which are 3.3v logic boards where the motordriver is a 5v logic board, now in Arduino while doing speed control 255 means 5v or even a high means 5v but in nodemcu/ESP32 this means 3.3v, so my question is how it will work ?

title: L298N Motor Driver with Nodemcu/ESP32

Answers: 1

body:
It's not a question of voltage. You make a basic mis-assumption:

> in Arduino while doing speed control 255 means 5v

No, it doesn't.  255 means "Provide a logic HIGH signal all the time".

128 means "Provide a logic HIGH signal 50% of the time".

The 255 (or whatever number) is the "duty cycle" of a PWM signal. That is a digital signal that can be LOW or HIGH which is switching on or off rapidly. The duty cycle defines the ratio of ON time to OFF time.

You're not providing a voltage - you're providing an ON/OFF signal.

As long as the HIGH voltage of that signal is above the *threshold* of the receiving device (the L298N in this case) then it will see it as an ON/OFF signal.

According to [the datasheet for the L298](https://www.st.com/resource/en/datasheet/l298.pdf) the HIGH logic threshold (VIH) is 2.3V. That means anything above 2.3V is seen as ON and anyting below that is seen as OFF (actually there is hysteresis, so it has to drop below 1.5V to switch to OFF).

So your 3.3V from the NodeMCU is above that ON threshold, so the ON/OFF PWM signal is received properly as such.

Incidentally, it's because of this PWM signal that motors make a whining sound when they start up slowly. Because of this most proper motor drivers run the PWM at above 25kHz instead of the 500-ish Hz of the Arduino, so that whine is above the threshold of human hearing.


body:
If I am programming an arduino and I wanted to communicate with the internet thru the esp2866 then is AT command the only thing that I can do?

I see a lot of this in the web

    void loop() {
     valSensor = getSensorData();
     String getData = "GET /update?api_key="+ API +"&"+ field +"="+String(valSensor);
    sendCommand("AT+CIPMUX=1",5,"OK");
     sendCommand("AT+CIPSTART=0,\"TCP\",\""+ HOST +"\","+ PORT,15,"OK");
     sendCommand("AT+CIPSEND=0," +String(getData.length()+4),4,">");
     esp8266.println(getData);delay(1500);countTrueCommand++;
     sendCommand("AT+CIPCLOSE=0",5,"OK");
    }

If I set my Board -> Arduino Uno, I was thinking I can use the following library [https://arduino-esp8266.readthedocs.io/en/2.7.4_a/esp8266wifi/readme.html][1]

    #include <ESP8266WiFi.h>

    const char* ssid     = "my-ssid";
    const char* password = "my-password";

    void setup() {
      Serial.begin(115200);
      // We start by connecting to a WiFi network

      Serial.println();
      Serial.println();
      Serial.print("Connecting to ");
      Serial.println(ssid);

      WiFi.begin(ssid, password);

      while (WiFi.status() != WL_CONNECTED) {
        delay(500);
        Serial.print(".");
      }

But I am getting

    exit status 1
    ESP8266WiFi.h: No such file or directory

Looks like the following library is only available when you set the Board-> Generic ESP8266 Module and is only used when you want to program the ESP8266 in the Arduino IDE?  Is this correct?

So in my question, does it mean that to communicate from the Arduino into the internet, I will be sending the AT command and communicate thru the SoftwareSerial.h?

  [1]: https://arduino-esp8266.readthedocs.io/en/2.7.4_a/esp8266wifi/readme.html

title: Is AT command the only way to connect from Arduino to esp2866?

Answers: 1

body:
> is AT command the only thing that I can do?

No. The AT commands are provided by the AT command firmware. You can replace that firmware with whatever you want.

It is common to write your own software for the ESP8266 to do your communication for you and communicate with other devices (including an Arduino) in whatever way is suitable.

Many times you don't even need the Arduino any more as the ESP8266 can do everything (it struggles with analog signals as there is only one rather inferior ADC pin).

> Looks like the following library is only available when you set the Board-> Generic ESP8266 Module and is only used when you want to program the ESP8266 in the Arduino IDE? Is this correct?

That is correct. That is for when you are writing your own ESP8266 firmware to replace the AT firmware.

> So in my question, does it mean that to communicate from the Arduino into the internet, I will be sending the AT command and communicate thru the SoftwareSerial.h?

Only if you retain the AT firmware on the ESP8266. To be honest that firmware is terrible and all the tutorials are bad. You should at the first available opportunity learn to program the ESP8266 directly and maybe retire the Arduino unless you need to use it as a glorified IO expander.


body:
I am trying to read out the Microchip MCP3903 six channel ADC using an ESP32 via SPI communication. The MCP3903 is powered with 5V and 3,3V and is connected with an external 3,57 MHz crystal. The ESP32 I use is the Olimex ESP32-EVB and the code is uploaded with the Arduino IDE. It works perfectly for other projects, so the ESP seems to be OK.

For the MCP3903 a library exists (https://github.com/mjklopfer/MCP3903) with an example that I am trying to run but nothing is happening. I have tried to use VSPI (GPIO 23, 19,18 and 5) and HSPI (GPIO 13, 12, 14, 15) but I am not getting a CLK signal when I check with the scope. I also tried to alter the code using pointers as suggested here: https://arduino.stackexchange.com/questions/55805/spi-digital-potentiometer-not-working-on-esp32, but also that is not changing anything.

You can find the code of the MCP3909 example that I am trying out below. I suppose that when the MCP is not connected, I would still see the CLK running? Is there something special that needs to happen with the GPIOs, like pull-up resistors or something the like? How can I check that the problem is software related or hardware related?

    /*
    mcp3903example.ino
    Arduino example for the MCP3903 - Example tested
    Extended from the Arduino Library for MCP3903 A/D Converter
     * MCP3903 Library
     * Kerry D. Wong
     * http://www.kerrywong.com, http://www.kerrywong.com/2014/05/10/mcp3903-library/, https://github.com/kerrydwong/MCP3903) * 5/2014
    Minor Arduino Feature extensions by Zhi Luo, Kaixin Chen, Yaxin "Erica" Deng, Yutian Ren, and Michael Klopfer, Ph.D.
    University of California, Irvine
    2018
    */

    #include <SPI.h>
    #include "MCP3903.h"

    //Set the gains and offsets for your ADC channels:
    #define ch0_gain 2.383490972 //these are values for calibration. By setting these values, reads will be the same as the inputs.
    #define ch0_offset -0.007884781 //the maximum read for each channel will be around 0.7866. The deviation for these values is around 2%

    #define ch1_gain 2.383490972
    #define ch1_offset -0.007884781

    #define ch2_gain 2.383490972
    #define ch2_offset -0.007884781

    #define ch3_gain 2.383490972
    #define ch3_offset -0.007884781

    #define ch4_gain 2.383490972
    #define ch4_offset -0.007884781

    #define ch5_gain 2.383490972
    #define ch5_offset -0.007884781

    MCP3903 mymcp3903;  //Initialize mymcp3903 object for the MCP3903

    void setup()
    {
        //esp.begin(); Needed with ESP8266 for ESP class functions
      Serial.begin(9600); //set serial comm at 9600 bps
      SPI.begin(); //Start SPI
      SPI.beginTransaction(SPISettings(1000000, MSBFIRST, SPI_MODE0));  //Start SPI transaction with defined parameters
            mymcp3903.init(10); // (10 for UNO; 15 for esp8266)Setings for your Arduino's/ESP8266's SPI pin used for interfacing(pinCS) - make sure this is the pin you have your CS on!
            mymcp3903.reset(MCP3903::OSR_256);
            mymcp3903.setGain(1,MCP3903::GAIN_8);
      //Need to initialize all channels to use
      SPI.endTransaction(); //End SPI transaction

    }

    void loop()
    {
      SPI.beginTransaction(SPISettings(1000000, MSBFIRST, SPI_MODE0));  //Start SPI transaction with defined parameters

      //Print out the ADC value of channel 0
      Serial.print("Channel 0 ADC Value: "); //Start your line here
        double ch0 = mymcp3903.readADC(0);
        double ch0Cal = (ch0* ch0_gain)+ch0_offset;
        Serial.println(ch0Cal);//Add value then end your line
      delay(10);  //Delay before next Ch read (totally optional)

      //Print out the ADC value of channel 1
        Serial.print("Channel 1 ADC Value: "); //Start your line here
        double ch1 = mymcp3903.readADC(1);
        double ch1Cal = (ch1* ch1_gain)+ch1_offset;
        Serial.println(ch1Cal);//Add value then end your line
      delay(10);  //Delay before next Ch read (totally optional)

      //Print out the ADC value of channel 2
        Serial.print("Channel 2 ADC Value: "); //Start your line here
        double ch2 = mymcp3903.readADC(2);
        double ch2Cal = (ch2* ch2_gain)+ch2_offset;
        Serial.println(ch2Cal);//Add value then end your line
      delay(10);  //Delay before next Ch read (totally optional)

      //Print out the ADC value of channel 3
      Serial.print("Channel 3 ADC Value: "); //Start your line here
        double ch3 = mymcp3903.readADC(3);
        double ch3Cal = (ch3* ch3_gain)+ch3_offset;
        Serial.println(ch3Cal);//Add value then end your line
      delay(10);  //Delay before next Ch read (totally optional)

      //Print out the ADC value of channel 4
      Serial.print("Channel 4 ADC Value: "); //Start your line here
        double ch4 = mymcp3903.readADC(4);
        double ch4Cal = (ch4* ch4_gain)+ch4_offset;
        Serial.println(ch4Cal);//Add value then end your line
      delay(10);  //Delay before next Ch read (totally optional)

      //Print out the ADC value of channel 5
      Serial.print("Channel 5 ADC Value: "); //Start your line here
        double ch5 = mymcp3903.readADC(5);
        double ch5Cal = (ch5* ch5_gain)+ch5_offset;
        Serial.println(ch5Cal);//Add value then end your line
      delay(10);  //Delay before next Ch read (totally optional)

        delay(100);  //Delay, then re-run loop to read sensors again
      //SPI.endTransaction(); //End SPI transaction - we are keeping this open for this example
    }

title: ESP32 SPI communication with MCP3903 not working

Answers: 0


body:
I would like to control a 5V relay with Wemos D1 R1 module through webserver. I'm using the following modules:
 - Tongling 5vdc Relay
 - Wemos D1 R1

I'm using the following schematic:
[![Sketch][1]][1]

and here is the code I'm using:

    #include <ESP8266WiFi.h>

    const char* ssid = "Myssidname";
    const char* password = "Myssidpass";

    int ledPin = D3;
    WiFiServer server(80);

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

     pinMode(ledPin, OUTPUT);
     digitalWrite(ledPin, LOW);

     // Connect to WiFi network
     Serial.println();
     Serial.println();
     Serial.print("Connecting to ");
     Serial.println(ssid);

     WiFi.begin(ssid, password);

     while (WiFi.status() != WL_CONNECTED) {
       delay(500);
       Serial.print(".");
     }
     Serial.println("");
     Serial.println("WiFi connected");

     // Start the server
     server.begin();
     Serial.println("Server started");

     // Print the IP address
     Serial.print("Use this URL : ");
     Serial.print("http://");
     Serial.print(WiFi.localIP());
     Serial.println("/");

    }

    void loop() {
     // Check if a client has connected
     WiFiClient client = server.available();
     if (!client) {
       return;
     }

     // Wait until the client sends some data
     Serial.println("new client");
     while(!client.available()){
       delay(1);
     }

     // Read the first line of the request
     String request = client.readStringUntil('\r');
     Serial.println(request);
     client.flush();

     // Match the request

     int value = LOW;
     if (request.indexOf("/LED=ON") != -1) {
       digitalWrite(ledPin, HIGH);
       value = HIGH;
     }
     if (request.indexOf("/LED=OFF") != -1){
       digitalWrite(ledPin, LOW);
       value = LOW;
     }

     // Return the response
     client.println("HTTP/1.1 200 OK");
     client.println("Content-Type: text/html");
     client.println(""); //  do not forget this one
     client.println("<!DOCTYPE HTML>");
     client.println("");

     client.print("Led pin is now: ");

     if(value == HIGH) {
       client.print("On");
     } else {
       client.print("Off");
     }
     client.println("

");
     client.println("Click here Turn relay ON
");
     client.println("Click here Turn relay OFF
");
     client.println("");

     delay(1);
     Serial.println("Client disconnected");
     Serial.println("");

    }

After uploading the code **successfully** and watching the monitor, the light gets turned on and I get the following message:

    16:02:20.400 -> WiFi connected
    16:02:20.425 -> Server started
    16:02:20.479 -> Use this URL : http://192.168.100.7/
    16:02:41.680 -> new client
    16:02:41.680 -> GET / HTTP/1.1
    16:02:41.680 -> Client disconnected

However, when I turn on or off the relay using the browser, nothing happens:

    19:38:56.010 -> new client
    19:38:56.010 -> GET /LED=ON HTTP/1.1
    19:38:56.010 -> Client disconnected
    19:38:57.016 -> new client
    19:38:57.016 -> GET /LED=OFF HTTP/1.1
    19:38:57.063 -> Client disconnected

However nothing happens to the light and relay doesn't click.

**a few more notes:**
 - I tried in upload the code with relay at high to disconnect the circuit but light is still on
 - Wemos Network name appears in my network list
 - It doesn't not respond to AT Commands

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

title: Controling 5V relay with Wemos D1 R1

Answers: 2

body:
Is the Wemos D1 R1 a 5V board, or 3.3V? If it's a 3.3V board, that's your problem. Get a 3.3V relay.

(From a little digging it looks like the Wemos is a 3.3V device. If so, that is your problem. Those "digital relays" are available in 5V and 3.3V models. Replace your 5V relay with a 3.3V relay.)

What are the current requirements of the relay, and what is the max current you can draw out of the Wemos? How are you powering the Wemos?

I would say break this into pieces and solve them separately. Put a multimeter (OR an LED with a current limiting resistor) on pin D3 and make sure the pin is turning on and off. If it is, it is a problem with your relay. If it's not, it's a problem with your sketch or your Arduino.

If the pin is turning on and off, try attaching the IN pin on your relay directly to +5V. Does your lightbulb light then?

body:
The issue lies with Wemos Module where it only outputs 3.3V which insufficient to 5V Relay so this can be solved by implementing 2N2222 Transistor as per schematic below.[![enter image description here][1]][1]

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


body:
I am using the default example SimpleWiFiServer that comes as an example from the ESP32:

    #include <WiFi.h>
    #include <WiFiClient.h>
    #include <WiFiAP.h>

    #define LED_BUILTIN 2   // Set the GPIO pin where you connected your test LED or comment this line out if your dev board has a built-in LED

    // Set these to your desired credentials.
    const char *ssid = "MyNetwork";
    //const char *password = "YourPassword";

    WiFiServer server(80);

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

      Serial.begin(115200);
      Serial.println();
      Serial.println("Configuring access point...");

      // You can remove the password parameter if you want the AP to be open.

      //tcpip_adapter_dns_info_t dns_info;
      //dns_info.ip.u_addr.ip4.addr = IPAddress(192,168,4,1);
      //tcpip_adapter_set_dns_info(TCPIP_ADAPTER_IF_AP, TCPIP_ADAPTER_DNS_MAIN, &dns_info);

      WiFi.softAP(ssid);
      IPAddress myIP = WiFi.softAPIP();
      Serial.print("AP IP address: ");
      Serial.println(myIP);
      server.begin();

      Serial.println("Server started");
    }

    void loop() {
      WiFiClient client = server.available();   // listen for incoming clients

      if (client) {                             // if you get a client,
        Serial.println("New Client.");           // print a message out the serial port
        String currentLine = "";                // make a String to hold incoming data from the client
        while (client.connected()) {            // loop while the client's connected
          if (client.available()) {             // if there's bytes to read from the client,
            char c = client.read();             // read a byte, then
            Serial.write(c);                    // print it out the serial monitor
            if (c == '\n') {                    // if the byte is a newline character

              // if the current line is blank, you got two newline characters in a row.
              // that's the end of the client HTTP request, so send a response:
              if (currentLine.length() == 0) {
                // HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK)
                // and a content-type so the client knows what's coming, then a blank line:
                client.println("HTTP/1.1 200 OK");
                client.println("Content-type:text/html");
                client.println();

                // the content of the HTTP response follows the header:
                client.print("Click here to turn ON the LED.
");
                client.print("Click here to turn OFF the LED.
");

                // The HTTP response ends with another blank line:
                client.println();
                // break out of the while loop:
                break;
              } else {    // if you got a newline, then clear currentLine:
                currentLine = "";
              }
            } else if (c != '\r') {  // if you got anything else but a carriage return character,
              currentLine += c;      // add it to the end of the currentLine
            }

            // Check to see if the client request was "GET /H" or "GET /L":
            if (currentLine.endsWith("GET /H")) {
              digitalWrite(LED_BUILTIN, HIGH);               // GET /H turns the LED on
            }
            if (currentLine.endsWith("GET /L")) {
              digitalWrite(LED_BUILTIN, LOW);                // GET /L turns the LED off
            }
          }
        }
        // close the connection:
        client.stop();
        Serial.println("Client Disconnected.");
      }
    }

That initializes the ESP32 as an Access Point. On my phone I am able to see the network MyNetwork. If I connect to it and then open a my browser and go to 192.168.4.1 I am able to see the default page.

**How can I change that code so that when I connect to that network it automatically open my browser going to http://192.168.4.1 ?**

When researching on the internet I found this library that does that [WiFiManager][1] . That library helps you connect to an existing WiFi network. I do not want to do that. I only want that when I connect to `MyNetwork` my default page opens up just like when you connect to guest networks on hotels etc.

[Other people on the internet have modified WiFiAPP.cpp and added these three lines of code][2]:

    tcpip_adapter_dns_info_t dns_info;
    dns_info.ip.u_addr.ip4.addr = IPAddress(192,168,4,1);
    tcpip_adapter_set_dns_info(TCPIP_ADAPTER_IF_AP, TCPIP_ADAPTER_DNS_MAIN, &dns_info);

That only makes my esp32 crash and does not work.

Has someone figure out a simple way to open a popup window (captive portal) pointing to http://192.168.4.1 once you connect to the ESP32 access point?

Lastly I found [this example][3] but that is using esp8266.

  [1]: https://github.com/tzapu/WiFiManager
  [2]: https://github.com/espressif/arduino-esp32/issues/400#issuecomment-355065883
  [3]: https://stackoverflow.com/questions/54583818/esp-auto-login-accept-message-by-os-with-redirect-to-page-like-public-wifi-port

title: ESP32 open "captive portal" on connected

Answers: 2

body:
Thanks to @Majenko I was able to find what I was looking for on the internet from [this link][1]. When I googled "captive portal" instead of the phrases that I was using I found a lot more examples.

This code opens a "captive portal" once I connect to the esp32 access point.

    #include <WiFi.h>
    #include <DNSServer.h>

    const byte DNS_PORT = 53;
    IPAddress apIP(192, 168, 1, 1);
    DNSServer dnsServer;
    WiFiServer server(80);

    String responseHTML = ""
      "<!DOCTYPE html><title>CaptivePortal</title>"
      "
Hello World!

This is a captive portal example. All requests will "
      "be redirected here.
";

    void setup() {
      WiFi.disconnect();   //added to start with the wifi off, avoid crashing
      WiFi.mode(WIFI_OFF); //added to start with the wifi off, avoid crashing
      WiFi.mode(WIFI_AP);
      WiFi.softAPConfig(apIP, apIP, IPAddress(255, 255, 255, 0));
      WiFi.softAP("DNSServer CaptivePortal example");

      // if DNSServer is started with "*" for domain name, it will reply with
      // provided IP to all DNS request
      dnsServer.start(DNS_PORT, "*", apIP);

      server.begin();
    }

    void loop() {
      dnsServer.processNextRequest();
      WiFiClient client = server.available();   // listen for incoming clients

      if (client) {
        String currentLine = "";
        while (client.connected()) {
          if (client.available()) {
            char c = client.read();
            if (c == '\n') {
              if (currentLine.length() == 0) {
                client.println("HTTP/1.1 200 OK");
                client.println("Content-type:text/html");
                client.println();
                client.print(responseHTML);
                break;
              } else {
                currentLine = "";
              }
            } else if (c != '\r') {
              currentLine += c;
            }
          }
        }
        client.stop();
      }
    }

  [1]: https://github.com/espressif/arduino-esp32/blob/master/libraries/DNSServer/examples/CaptivePortal/CaptivePortal.ino

body:
When providing HTTP server you generally have two options:

1.  Using WebServer class and set handlers for roots. The parsing and handling of HTTP header is done by the library.
2. Use WifiServer and receive the HTTP message with header included and handler everything by your own.

If you are doing number 1 and pretend using by connecting with an Android device I suggest adding a handler for the error case showing the captive portal:

    server.onNotFound(handleRoot);

I noticed that for Android 10, to properly detect the captive portal and make the phone to show "Touch to log in the network" message is necesary. If not you must navigate to any HTTP address and let the DNS do the job for you (not HTTPS).