text:
How to repeat the code
I want to make my biped robot keep walking, but it only move for twice, this biped robot project is important for my Capstone project. The code below is the code that I used
#include <Servo.h>

int HipR_Pin = 9;
int HipL_Pin = 10;

int KneeR_Pin = 5;
int KneeL_Pin = 6;

int AnkleR_Pin = 3;
int AnkleL_Pin = 11;

Servo HipR;
Servo HipL;

Servo KneeR;
Servo KneeL;

Servo AnkleR;
Servo AnkleL;

void setup() {
  HipR.attach(HipR_Pin);
  HipL.attach(HipL_Pin);
  KneeR.attach(KneeR_Pin);
  KneeL.attach(KneeL_Pin);
  AnkleR.attach(KneeR_Pin);
  AnkleL.attach(KneeL_Pin);
}

void loop() {

  for (int i=0; i < 7; i++)
  {
    RightStep1;
    LeftStep1;
    RightStep2;
    LeftStep2;
    RightStep3;
    LeftStep3;
    RightStep4;
    LeftStep4;
  }
  ;
}

void RightStep1()
{
  HipR.write(80);
  HipL.write(80);
  KneeR.write(100);
  KneeL.write(100);
  AnkleR.write(20);
  AnkleL.write(20);

}

void LeftStep1()
{
  HipR.write(90);
  HipL.write(90);
  KneeR.write(70);
  KneeL.write(70);
  AnkleR.write(20);
  AnkleL.write(20);

}

void RightStep2()
{
  HipR.write(70);
  HipL.write(70);
  KneeR.write(80);
  KneeL.write(80);
  AnkleR.write(10);
  AnkleL.write(10);

}

void LeftStep2()
{
  HipR.write(60);
  HipL.write(60);
  KneeR.write(90);
  KneeL.write(90);
  AnkleR.write(20);
  AnkleL.write(20);

}
void RightStep3()
{
  HipR.write(40);
  HipL.write(40);
  KneeR.write(60);
  KneeL.write(60);
  AnkleR.write(10);
  AnkleL.write(10);

}

void LeftStep3()
{
  HipR.write(50);
  HipL.write(50);
  KneeR.write(70);
  KneeL.write(70);
  AnkleR.write(20);
  AnkleL.write(20);

}
void RightStep4()
{
  HipR.write(60);
  HipL.write(60);
  KneeR.write(60);
  KneeL.write(60);
  AnkleR.write(10);
  AnkleL.write(10);

}

void LeftStep4()
{
  HipR.write(70);
  HipL.write(70);
  KneeR.write(50);
  KneeL.write(50);
  AnkleR.write(20);
  AnkleL.write(20);

}

when describing a problem, you have to say exactly what happens ..... but it only move for twice does not describe the observed action ..... because it could mean that the robot takes two steps or it could mean that only two of the servos move or it could mean that one servo moves twice .... each of those conditions would be caused by different program bugs

This may not be a direct answer to your question but... when I see so
much code repetition, I cannot help but suggest you try to avoid
repeating yourself. All your Step() functions do exactly the same
actions, only with different data. You can then factor the actions
into a single function, and provide it different data as parameters.
There are many ways to achieve this in C++. I am going to show four of
them, in order from the most basic to the most esoteric.
The simplest one is to use a plain function and give it the angles as
parameters. This is basically what Michel Keijzers’ answer suggests. My
take on it would be
void Step(uint8_t hip, uint8_t knee, uint8_t ankle)
{
    HipR.write(hip);
    HipL.write(hip);
    KneeR.write(knee);
    KneeL.write(knee);
    AnkleR.write(ankle);
    AnkleL.write(ankle);
}

which you can then use in the main loop as
Step( 80, 100,  20);  // right 1
Step( 90,  70,  20);  // left 1
...

The next step in code modularity would be to group all the angles for a
single step into a compound data structure called a struct, then the
function to perform a step takes a single parameter which is this data
structure:
struct Step {
    uint8_t hip;
    uint8_t knee;
    uint8_t ankle;
};

void doStep(Step s)
{
    HipR.write(s.hip);
    HipL.write(s.hip);
    KneeR.write(s.knee);
    KneeL.write(s.knee);
    AnkleR.write(s.ankle);
    AnkleL.write(s.ankle);
}

These structs would be defined as
Step RightStep1 = { 80, 100,  20};
Step LeftStep1  = { 90,  70,  20};
...

and used in loop() as
doStep(RightStep1);
doStep(LeftStep1);
...

One step further, you can embed the function within the data structure.
The embedded function then becomes a “method” of the data structure
which is now called an “object”:
struct Step {
    uint8_t hip;
    uint8_t knee;
    uint8_t ankle;
    void perform() {
        HipR.write(hip);
        HipL.write(hip);
        KneeR.write(knee);
        KneeL.write(knee);
        AnkleR.write(ankle);
        AnkleL.write(ankle);
    }
};

The structs can be defined just as before, and used as
RightStep1.perform();
LeftStep1.perform();
...

One last technique involves making the objects themselves behave as
functions that can be called. This kind of callable object is called a
“functor”, and is kind of syntactic sugar over a method call. We just
have to rename the relevant method as operator():
struct Step {
    uint8_t hip;
    uint8_t knee;
    uint8_t ankle;
    void operator()() {
        HipR.write(hip);
        HipL.write(hip);
        KneeR.write(knee);
        KneeL.write(knee);
        AnkleR.write(ankle);
        AnkleL.write(ankle);
    }
};

The structs are still defined in the same way, but now they can be used
as if they were plain functions:
RightStep1();
LeftStep1();
...

I suggest you use whatever technique you feel the most comfortable with.
There is a logic progression though: the more you improve your C++
skills the more comfortable you will be with the latest ones.

In addition to @Gerben's answer, you aren't giving any time for your movements to complete.  .write() doesn't wait for the movement to complete - it just sets the target angle.  You should add enough delay(...) calls to wait for your movements to finish before you start a new one.

Instead of all the different step functions you can better parameterize them for example
void LeftStep4()
{
  HipR.write(70);
  HipL.write(70);
  KneeR.write(50);
  KneeL.write(50);
  AnkleR.write(20);
  AnkleL.write(20);
}

will be
void LeftStep4()
{
  Move(70, 70, 50, 50, 20, 20);
}

and create a function
void Move(int hipR, int hipL, int kneeR, int kneeL, int ankleR, int ankleL)
  HipR.write(hipR);
  HipL.write(hipL);
  KneeR.write(kneeR);
  KneeL.write(kneeL);
  AnkleR.write(ankleR);
  AnkleL.write(ankleL);
}

The other functions will also be one liners like the first function LeftStep4.

To call a function you need to add parentheses after the function name.
void loop() {

  for (int i=0; i < 7; i++)
  {
    RightStep1();
    LeftStep1();
    RightStep2();
    LeftStep2();
    RightStep3();
    LeftStep3();
    RightStep4();
    LeftStep4();
  }
  ;//<<--also remove this stray semi-colon
}


text:
Arduino keypad variables to serial port
I've been trying, for over a week now, to create a program that will store my keypad presses into variable, and with a press of an enter, it will switch to the next variable to store the presses. The program is made to load addresses (mainly IP addresses) to different devices over serial connections. Because there are different types of addresses, each time the user press enter in the keypad (made the # button to a '\r' char) the program needs to switch to the next type of address and get the key presses from the keypad and store them until the next '\r' press. My problem is that I don't know how to store those addresses in the Arduino, and switch to a different "char" (I used char because I didn't knew how to convert them to store key presses into string) every '\r' press. I've included the handler for this part of my code. This is my first post here so if anything is missing let me know. thanks ahead.
bool handlerManualEntry( void )
{
    static uint8_t stateManualEntry = statesFunc::ST_INIT;

    char keyval = ReadKey();
    switch( stateManualEntry )
    {
        case    statesFunc::ST_INIT:
            //do whatever inits you need here (screen, variables etc)

            stateManualEntry = statesFunc::ST_RUN;

        break;

        case    statesFunc::ST_RUN:
            //is there a keypress?
            if( keyval != NO_KEY )
            {
                switch( keyval )
                {

                    case    '\r':
                        //when we get a return, send it to the serial port
                        Serial.print( '\n' );
                        u8g2log.print('\f');
                        for(int i=0; i<6; i++)
                        {
                          if(i == 0)
                          {
                          Serial.print(ethernetIP);
                          }
                        else if(i == 1)
                          {
                          Serial.print(ethernetSubnet);
                          }
                        else if(i == 2)
                          {
                          Serial.print(ethernetGetway);
                          }
                        else if(i == 3)
                          {
                          Serial.print(vmeIP);
                          }
                        else if(i == 4)
                          {
                          Serial.print(vmeSubnet);
                          }
                        else if(i == 5)
                          {
                          Serial.print(eventPort);
                          }
                        else if(i == 6)
                          {
                          Serial.print(timeOut);
                          }
                        }
                        //and finish out by returning the state to INIT and returning true
                        //stateManualEntry = statesFunc::ST_INIT;
                        //return true;

                    break;
                    case 'D':
                          u8g2log.print('N');
                          Serial.print('N');
                    break;

                    case 'C':
                          u8g2log.print('Y');
                          Serial.print('Y');
                    break;

                    default:
                        //for any other key, print to the serial port and LCD
                        u8g2log.print(keyval);

                        enterAddresses();
                    break;

                }

            }

        break;

    }

    return false;

}

void enterAddresses()
{
  int x;
  if(keyval != '\r')
  {
    if(pointer == 1)
    {

      keyval = keypad.getKey();
      u8g2log.print(keyval);
      ethernetIP += keyval;
    }
    else if(pointer == 2)
    {
      keyval = keypad.getKey();
      u8g2log.print(keyval);
      ethernetSubnet += keyval;
      }
    }
    else if(pointer == 3)
    {

      keyval = keypad.getKey();
      u8g2log.print(keyval);
      ethernetGetway += keyval;

    }
    else if(pointer == 4)
    {
      keyval = keypad.getKey();
      u8g2log.print(keyval);
      vmeIP += keyval;
    }
    else if(pointer == 5)
    {
        keyval = keypad.getKey();
      u8g2log.print(keyval);
      vmeSubnet += keyval;
    }
    else if(pointer == 6)
    {
      keyval = keypad.getKey();
      u8g2log.print(keyval);
      eventPort += keyval;
    }
    else if(pointer == 7)
    {

      keyval = keypad.getKey();
      u8g2log.print(keyval);
      timeOut += keyval;

    }
    pointer++;
    u8g2log.print('\f');

}

char keys[ROWS][COLS] = {
  {'1','2','3','A'},
  {'4','5','6','B'},
  {'7','8','9','C'},
  {'.','0','\r','D'}
};

byte rowPins[ROWS]={39,41,43,45};
byte colPins[COLS]={31,33,35,37};

//Create an object of keypad
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );
char keyval;

please format all of your code, not just parts of it ... it is unreadable the way you presented it

what is the reason for using for(int i=0; i<6; i++) to run seven Serial.print() commands in sequence?

Consider constraining the user and simplifying your code.

Simplify your code by putting rules on how the IP address is entered. When entering the IPv4 address in dot-decimal notation require that all 3 digits are always used for each of the four quad-dotted notation values.  For example, the IPv4 address 192.168.10.20 would be entered as "192168010020".

Eliminate unnecessary keypad buttons.

The only keys required for the above scheme are 0, 1, 2, ..., 9.  No other keys need to be detected or supported by additional software.

Start simple, get that working then add complexity.

Essentially, a state machine is most often used as the underlying coding pattern when interfacing with a user.  Keeping track of what the user has done, the current state the user is in and where the user may go is the job of the state machine.  To implement the above, the state machine will need to be complex enough to track the 1s, 10s & 100s position of each quad-dotted notation values as well as which quad-dotted notation value is currently being entered.  This is complex enough for a first pass.  Later, in subsequent passes, consider adding an "abort" key for when the user feels a new attempt is in order.  Still later, consider adding a "back space" key.  Finally, consider adding an "enter" key and dripping the 3 digit per quad-dotted notation value requirement.

source: Stack Exchange

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

sort: votes


text:
boards.txt - how to create sub-menu (NOT new board!!!)
Arduino 1.8.19
Is it possible to create a sub-menu inside boards.txt that would allow having the boards grouped for example by the manufacturer?
If it is possible, please provide an example or at least documentation for the language which is used for boards.txt.
I don't want to add a new board.

No, it's not possible.
The board menu (defined here) is a single flat menu with "scroller" added to it.
To have multiple layers of menu you'd have to rewrite that entire part of the IDE.

Thank you very much, this is truly a great answer!

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


text:
Reading data from an Ohaus Defender 3000 with a RS-232 shield
I have a project where we have to read the weight from an Ohaus Defender 3000 by using an Arudino Mega 2560 and a RS-232 shield. Right now we have the RX of the Arduino to the TX of the shield, and the TX of the Arduino to the RX of the shield. In our code, we get both the RX and the TX lights of the shield to light up but we can't receive data from the scale into the Arduino. Could someone help me understand what is going on or am I doing something wrong. This is the following code that I used for the Arduino. I found this code at: Reading Arduino Serial Input. Thank you for the help in advance.
#define HWSERIAL Serial1

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

void loop() {
  int incomingByte;

  if (Serial.available() > 0) {
    incomingByte = Serial.read();
    Serial.print("USB received: ");
    Serial.println(incomingByte, DEC);
    //HWSERIAL.print("USB received:");
    //HWSERIAL.println(incomingByte, DEC);
  }
  if (HWSERIAL.available() > 0) {
    incomingByte = HWSERIAL.read();
    Serial.print("UART received: ");
    Serial.println(incomingByte);
    //HWSERIAL.print("UART received:");
    //HWSERIAL.println(incomingByte);
  }
}

I don't know the specific instrument you're trying to connect to, but have you configured it to send output to its serial port with the speed you expect in your sketch (9600 baud)? Also, for troubleshooting, have you tried to connect your instrument to a PC (via usb to serial) to see if it outputs any data on the serial port?

Can you provide a photo of your hardware setup, and the full code for your project?  Please use the "code sample" formatting widget (the "{}" icon) to surround the code section, and look at the preview to make sure the code is formatted correctly.
Just a guess, but you may have the TX/RX lines to the scale connected to 'Serial' on the Mega instead of 'Serial1'. That would definitely cause problems


text:
Hello, Please can someone assist me with in checking my code?..I try to generate a high freq signal (at least 150KHz) with Arduino Mega, CTC Mode
void setup() {
  pinMode(9, OUTPUT);
  pinMode(10, OUTPUT);
  TCCR2A = TCCR2A & B01010000 | B00000010 ; // CTC mode activated, Toggle OC2A
  TCCR2B = TCCR2B & B11110000 | B00000001;//Prescaller set
  TCNT2=0;//Start Counting ffrom 0
  OCR2A=127;//Set TOP value)

}

void loop() {

}

It may not be strictly necessary, but it would probably good to say what you're seeing instead of the expected signal.

TCCR2A = TCCR2A & B01010000 | B00000010 ; // CTC mode activated, Toggle OC2A

What you have here clears TCCR2A's COM2A1 but preserves its original COM2A0.
When I print out TCCR2A prior to modification, I see a value of 0x01 (COM2A is 0; both bits of it).
Printing out TCCR2A after you've manipulated it 0x02.  So, in TCCR2A, you
are winding up with zeros for your COM2A1 and COM2A0 bits, which is all
cases is "Normal port operation; OC2A disconnected".  That is, you're not going
to see whatever signal you might otherwise have configured to generate because
it just hasn't been routed to the (Arduino pin 10)/(gpio PB4)/OC2A
It's usually better to not rely on the bootloader and the start code and the
Arduino core to have left a hardware register in a particular state.
The following is probably closer to what you intended:
TCCR2A = B01010000 | B00000010 ; // CTC mode activated, Toggle OC2A

It's still not entirely correct to the problem description (not the correct frequency), but it does send a signal out of the Arduino MEGA's digital pin 10.  It also is configured to toggle OC2B, so unless you wanted that:
TCCR2A = B01000000 | B00000010 ; // CTC mode activated, Toggle OC2A

This can be made more readable by using the bit field names for the given:
TCCR2A =
      (1 << COM2A0)  // CTC mode activated (note COM2A1 is zero)
    | (2 <<  WGM20); // lower two bits of WGM value 2

You can do this same sort of thing for TCCR2B. And likewise, it is best that you don't rely on the previous value of TCCR2B.
With OCR2A = 127;, you are toggling (reaching a half-period) every 128/16,000,000 seconds, or a 8 uS half-period, for a 16 uS period. Generating 62.5 KHz, which is below your target 150 KHz.  Knowing it's half-periods, an OCR2A of 63 gets you to 125 KHz.
An OCR2A of 52 or less gets you into the greater than 150 kHz range, at least if we take your 16 MHz clock rate very seriously. You might need to be a little lower to be sure.


text:
RX and TX pins on esp32
hello guys i'm new to this field i really need your help i want to wire a GSM module (SIM808) to a ESP32 board using the TX and RX pins so the pins are labeled RX and TX no pin number like the others how can i declare them in the code.
i already tested the code on an arduino uno on pins 0 and 1 (RX and TX) and it works fine here is the board i'm using :
i already tried using pins 16 and 17 but didn't work i need to try using pins number 40 and 41 according to image below

"Didn't work" is not very descriptive. Please show your code and how you have connected the module. It may be good to known that the ESP32 has a very flexible serial port configuration and serial I/O can be mapped to most of the GPIO pins.

Tx and Rx is used by Serial port for your Serial Monitor. Unlike Arduino Uno, which only has one Serial port, ESP32 has 3. You can use the TxD2 (GPIO17) and RxD2(GPIO16) for connecting to your SIM808 module. You uses the port with Serial2.begin(115200).

First off, thank you for all the guidance and support you've provided. As a beginner in the world of Arduino and embedded systems, it's been tremendously helpful.
The main issue I was facing had to do with not knowing how to declare the TX and RX pins in my C++ code, especially when these pins weren't labelled with their GPIO numbers like the others on my ESP32 board. After a bit of research and reading through your comments, I learned that these pins can simply be declared using their GPIO numbers, which are indicated on the schematic of the board.
For instance, to utilize RX0 and TX0, they need to be declared as 3 and 1 respectively. Here's an example:
 #define RXD 3  //RXD
    #define TXD 1  //TXD

    HardwareSerial SIM808(2);

void setup()
{
  //
  //
   SIM808.begin(9600, SERIAL_8N1, RXD, TXD);
}

I was able to get the SIM808 module working with this method, but I'm noticing that the system isn't always consistent. Sometimes it takes a long time to execute commands, which is something I will have to look into.
I just wanted to express my gratitude for the warm welcome and helpful guidance I've received here. This being my first post, I was worried about asking a "dumb question," but the community has been nothing but supportive.
As I continue to learn and explore more about embedded systems, I'm sure I'll be back with more questions, and hopefully, in time, some answers of my own to contribute!

this is a very bad advice. You want to use SoftwareSerial on hardware Serial pins? and this hardware Serial is already wired to the USB chip which communicates with the computer. You can use Serial2 on RX2/TX2 pins. Serail2 already exists as an object and is initialized for the pins. (as already mentioned in the comment below the Q)

Don't use SoftwareSerial on a device that has enough hardware serial ports to do the job.

can you provide more information about SoftwareSerial and HardwareSerial to help me better understand and also i'm running out of pins in my project is there any solution to reduce the number of pins or use the same pins for multiple purposes?

Hach Rbh, https://en.wikipedia.org/wiki/Bit_banging


text:
Arduino atmega328p
This program should prompt the user for an encryption key to be input through the serial
monitor. The encryption key contains 16 characters. However, the message that will be
encrypted can be up to 128 characters. As such, when storing the encryption key in the
EEPROM, you should repeat it so that it fills locations 0-127.
in the code, I'm trying to repeat the 16 character key 8 times
volatile bool prese_button = false;
String Password;
int counter = 8;
boolean right_pass;
void setup() {
  DDRD &= 0b11111011;
  PORTD |=0b00000100;
  EICRA |= 0b00000010;
  EIMSK |= 0b00000001;
  Serial.begin(9600);
}

void loop() {
  Serial.println("Please enter a 127 character password:");
  while (Serial.available() == 0) {}  //wait for serial terminal to be ready
  Password = Serial.readString();
  Serial.print("your password is: ");  //just to verify it was read correctly
  Serial.println(Password);
  for ( int j = 0 ;j < 128; j++) //   28 char
  {
    for (int i = 0; i<16 ; i++) {     //16 char
      EEPROM_write ( (j), Password[i] );
    }
  }
}

And what exactly is the problem?

I don't think your code does what you've described. But what exactly are you asking?

   for ( int j = 0 ;j < 128; j++) //   28 char
  {
    for (int i = 0; i<16 ; i++) {     //16 char
      EEPROM_write ( (j), Password[i] );
    }
  }

In these two for loops you are writing 128 times 16 characters.  That seems more than you described in your post.  If you have 16 things and need to repeat to fill 128 slots then you need 128 / 16 = 8 repeats of the 16 character sequence.  It's just basic math.  So that outer loop should count to 8, not 128.
for ( int j = 0 ;j < 8; j++) //  8 repeats of the 16 char
      {
        for (int i = 0; i<16 ; i++) {     //16 char
          EEPROM_write ((i + (16*j)), Password[i] );
        }
      }

Yes, and you'd have to calculate the address.  I'll add an example to the answer.


text:
I2C EEPROM "hangs" on endTransmission()
I am working on the 24LC256 EEPROM, wired as such, except 3.3v to the EEPROM, with 'scope clamped on SDA and SCL. I'm using an address scanner script with a few tweaks, 57600 baud, 10kOhm pullups, 100000 I2C clock, and some serial prints for snooping:
for(address = 1; address < 127; address++ ) {
    Serial.printf("\n%02x", address);
    Wire.beginTransmission(address);
    Serial.printf(",");
    error = Wire.endTransmission();
    Serial.printf(".");
    Serial.flush();
    if (error == 0) {
      Serial.printf("I2C device found at address 0x%02x", address);
      Serial.println("  !");
      nDevices++;
    }
    ...

When the loop hits the address corresponding to the jumpers (pins 1, 2, 3 correspond to address 0b01010abc, aka 0x5?, where ? = binary encoding of those pins), it just sorta hangs:
4c,.
4d,.
4e,.
4f,.
50,

(here I have 1, 2, 3 all low, so the chip responds to addr 0x50). Since it's hitting , but not ., I know it's hanging at Wire.endTransmission(). It always hangs at endTransmission at the address encoded by the jumpers.  SCL is low and SDA is high.
Scope trace looks fine counting through the addresses.
Trace of address not found.
Trace of hanging at address.
gif of cycling through last few addresses.
I'm on an Adafruit Feather nrf52 BLE, if that matters.

Can you check, which circuit is holding SCL low? (The feather or the EEPROM) SCL can be hold low by the slave for slowing down the master, if the slave is not ready or needs some time to process previous data.

@chrisl how can I check that? I tried sticking my scope on a shunt resistor on SCL, that just pulled everything low (probably b/c of the scope ground). I think I need an inamp or something.

Then you most likely connected it wrong. The scope has a high impedance, it should not pull anything down. Measure the voltage with the scope between the SCL pin of the feather and ground of feather

How does that tell me whether master or slave is pulling it low though?

Sorry, should have described it. Attach the scope to feather SCL. When SCL is low, unconnect your slave and check the voltage again. If it goes up the slave was holding it low

@DeusXMachina Looks like they have recently fixed this bug: https://github.com/adafruit/Adafruit_nRF52_Arduino/commit/38047231b1a577f3b7821374ded98efc3463268c

@DeusXMachina You could try to add a write of a single byte.

Because of the way that the I2C library works, the only place it can hang is on the endTransmission. The other calls just buffer stuff up in memory.
There is probably some electrical issue. For example, the pull-up resistors might be better as 4.7k.
There is another library which handles transmission a bit differently which might resolve the hanging.
However if it is hanging there are probably other issues (cable lengths, pull-up resistors, noise) that are the underlying issue.
The standard library waits in a tight loop for certain interrupts to arrive, and if they don't arrive it hangs indefinitely.

except 3.3v to the EEPROM

You may well need a level-shifter. It's all very well only sending out 3.3V to the EEPROM, but the rest of the circuit is dealing in 5V not 3.3V. You can get suitable level shifters quite cheaply.
Why are you using 3.3V anyway? That chip can handle 5V. I have a post about that exact chip which works fine there.

Hi Nick, I'm using 3.3 because the NRF52's logic pins are all 3.3. I should have made that more obvious. The Feather nRF52 is 3.3, so the whole layout is on 3.3. The source image I used shows an UNO. The EEPROM should handle 1.8-5.5V. But I think you are right about the pull up resistors. I've been reading that I2C is very touchy when it comes to capacitance of the system and the rate of those pull ups.

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


text:
Arduino-based mains frequency monitor follow-up
Following my
previous question, I'm getting closer to thinking about putting together this mains frequency monitor. I would just like to do a sanity check on my electronics before I order the components and the board. Please keep in mind I am not qualified in this so I have had to research how all this will work.

A and B inputs will accept power from a 16VAC 1.25A unregulated power pack.
C1 is a 1µF 25V 85°C ceramic capacitor. I guess this is mostly unnecessary as the power pack should filter any DC bias, but it won't hurt.
D1 is an IN4001 1A standard recovery diode.
R1 is a 300ohm 500V 3W resistor. The RMS power is 16VAC, which is half-wave rectified, so that's sqrt(2) * 16 = ~24V peak @ 300ohm = 80mA peak, and about 25mA on average (right?)
IC1 is a 4N28 optocoupler. It's weird, in one data sheet I see 80mA max forward current on inputs but in another I see 60mA. Anyway, the average should be 25mA so I guess that's probably going to be okay?
The Arduino I will use is the Arduino Micro, as it's quite small and also has a 16Mhz crystal oscillator that will provide a more stable clock than a ceramic resonator. The Arduino will be powered by USB, which I believe is 5V. The digital I/O pins I believe will also operate at 5V and are rated at 40mA max.
C will come from one of the Arduino's digital output pins, and D will go to the Arduino's GND.
R2 is a 150ohm 500mW 250V resistor, that should ensure the C→D current does not exceed 40mA @ 5V.
Now, assuming the components look okay and the circuit looks okay (I assume the circuit is fine), I just had some questions:

Do I need to add anything to the output of the 4N28 coming from the input? I think with a regular transistor, some of the base current gets added to the collector current?
What can I expect the response on the output of the 4N28 to look like? I assumed that it would more-or-less be a square wave, where even a tiny current on the input would activate the transistor and allow the output current to flow freely on the other side, but someone has suggested that this might not be the case?
The way it is set up, the Digital I/O pin can be "trying" to output or not, and that's basically irrelevant to what the transistor is doing. When the transistor is on, the output current from the pin will successfully flow to GND. I assume there is a way to detect this in the Arduino? Something like setting the output pin to 1 and check in loop when there is or is no current flowing?

Thank you!

3: your circuit will not work. Think pushbutton where the optocoupler is the button.

The capacitor is pointless. There can be no DC offset since there is no reference for it to be offset from. All it will do is mess with your current, screwing your power factor.

@Majenko thanks, I can remove the capacitor. I don't understand your explanation about why the circuit will not work? Or how to fix it?

You make poor assumptions about how GPIOs and transistors work. In this situation the transistor is merely a switch. Treat it as such. That means pull up resistor to VCC, and GPIO set to input mode.

Oh, and program it to use interrupts or, better, the Input Capture peripheral.

@Majenko ok so it's just a minor change: +5V goes to C, D goes to Digital I/O pin, and digital I/O pin goes to GND via a resistor? Do I also need a resistor from the D to the pin to ensure it's 40mA?

To ensure what is 40mA?

@Majenko the current from the +5V to the digital I/O pin via the opto. On the PIC, I'm pretty sure you need to put resistors from VCC to the digital inputs.

That only makes sense if the pin is an output. The only resistor you need on the pin is a pullup like a button.

@Majenko Arduinos arrived yesterday and the transformers arrived today. I got it set up and it's working great. I have 2 decimal places with micros() and I will convert to timer1 later for 3 decimal places. I wired it up differently, thought. I have the pin connected straight to ground, and the +5V going to the pin via the opto.

You should remove the capacitor. It won't remove any DC offset because there can be no DC offset. From where would the DC offset be relative? There is only two points in the circuit, and both of them are direct from the transformer and is an AC waveform. There is no concept of a DC offset in such a circuit.  All the capacitor will do is impose a phase change between the current and voltage of the AC waveform limiting the current during the conducting period of the diodes. You have a resistor for that function.
You make some incorrect assumptions about how to read the data. You talk about outputting a signal and somehow finding out if the transistor is on or not by if that signal is being output. That's completely backwards. Instead you should treat the transistor like a simple pushbutton and provide it with a pullup (or pulldown if you prefer) resistor, like this:

simulate this circuit – Schematic created using CircuitLab
You should feed the signal into an interrupt-enabled pin (such as D2 on the Uno as shown) so that an interrupt can be used for capturing the incoming edge time. Better would be to use the Input Capture peripheral, but that is harder to program for as there is no (AFAIK) library for it.
Yes, it would be possible to use the internal pullup resistor of the input pin instead of an external one, however using an external one allows you to fine tune the resistance which, coupled with the gate capacitance of the input pin, forms a low-pass filter limiting the frequency range you can monitor. At 50Hz it shouldn't be a problem though, so the choice is yours. Personally I use an external one.

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


text:
Problem with SIM800L GSM module and servo
I have a SIM800L GSM module like in this link, .
.
The problem is when I connect the GSM to my Arduino Uno the GSM turns on for a while and then turns off. I tried to connect it with a 9-volt battery and an LM7805 voltage regulator, but I have the same problem. Attached to the Arduino are an LM35 temperature sensor, two LEDs, a buzzer, an LCD, a GSM module, a gas sensor and a servo.
The other problem is with the servo. I tested the servo and it works fine but when the servo stops moving, it starts to shake. I do not know what the problem is.

9V batteries are useless. They are only any good at powering smoke alarms. Use a proper power supply or better batteries (6xAA or 2S Lithium Ion).

But I used LM7805 with battery to drop the voltage down! so you recomnded to me to use one of these,(6xAA or 2S Lithium Ion).?

You "drop the voltage down" by throwing away about half of it as heat. The current remains minuscule since the battery can't provide much (which is where your problem lies). You either need a source that can provide more current (6xAA or 2S Li-Ion) or a switching regulator that can convert the excess voltage into current.

Hi Majenko.. i used 6xAA but it is still did not work i donot know why, if u know other way to produce 3.5v and 2A let me know because i think my problem in the current .

Look for a 5v UBEC from somewhere like hobbyking.

You SIM800 module will pull 2Amps when its transmitting.  If your servo is also trying to overcome the inertia at the start of a movement it will pull 4+ times its normal running current.
A 9 volt battery will let you pull a couple of hundred milliamps.  So when the GSM transmits you system will shutdown.
You need a proper power supply or a battery pack that can put out these levels of peak current (3+Amps)

What did you mean by battery back ? And if i got it how can i connect it and connect it to what? I'm afriade of u because i did not understand it.

A battery pack, like 4xAA batteries or 2x3.7vLipo, etc.  You are going to power source that can deliver a peak current of 3Amps or more at 5V.  To start with it will be cheaper to use a plug in power source, once you have verified that your system works you can try and find a "battery pack" that will deliver the current you need.


text:
Multiple VL6180X distance sensors interactive problem
I am trying to use a VL6180X distance sensor and an Arduino Uno board for individual sensor doing individual distance sensing. This sensor follows the I2C protocol. Since for the same type of sensor, the I2C protocol says that they would all have the same address, I am thinking about using the chip enable pin (GPIO00) on the sensor chip to toggle sensor when doing the distance measuring.
I am able to update the address of the sensor group now. But I think to obtain individual results from different sensors on the Arduino serial monitor, right now I can only do one time setup sensor thing (like I couldn't update and toggle around different sensors). Once I started to do that, the results from the serial monitor were wrong. Any advice how I can continue to toggle around the sensor and make them work using the GPIO00 pin?
The code I'm using is:
#include <Wire.h>
#include <VL6180X.h>
#define Address1 0x20
#define Address2 0x22
#define Address3 0x24

VL6180X sensor;

int pin2 = 2;
int pin3 = 3;
int pin4 = 4;

void setup() {
  Serial.begin(9600);
  Wire.begin();
  pinMode(pin2,OUTPUT);
  pinMode(pin3,OUTPUT);
  pinMode(pin4,OUTPUT);
  digitalWrite(pin2,HIGH);
  digitalWrite(pin3,HIGH);
  digitalWrite(pin4,HIGH);
  sensor.init();
  sensor.configureDefault();
  sensor.writeReg(VL6180X::SYSRANGE__MAX_CONVERGENCE_TIME, 30);
  sensor.writeReg16Bit(VL6180X::SYSALS__INTEGRATION_PERIOD, 50);
  sensor.writeReg16Bit(VL6180X::INTERLEAVED_MODE__ENABLE,0);
  sensor.setTimeout(500);
  sensor.stopContinuous();
  delay(300);
  sensor.startInterleavedContinuous(100);
}

void loop() {
  hello2();
  delay(1000);
}

void hello1(){
  sensor.setAddress(0x29);
  Serial.println(sensor.readReg(0x212),HEX);
  sensor.setAddress(Address1);
  sensor.writeReg(0x212,Address1);
  Serial.println(sensor.readReg(0x212),HEX);
  Serial.println();
  digitalWrite(pin2,HIGH);
  digitalWrite(pin3,LOW);
  digitalWrite(pin4,LOW);
  Serial.print("Ambient 1: ");
  Serial.print(sensor.readAmbientContinuous());
  if (sensor.timeoutOccurred()) { Serial.print(" TIMEOUT"); }
  Serial.print("\tRange 1: ");
  Serial.print(sensor.readRangeContinuousMillimeters());
  if (sensor.timeoutOccurred()) { Serial.print(" TIMEOUT"); }
  Serial.println();
  sensor.writeReg(0x212,0x52);
  digitalWrite(pin2,HIGH);
  digitalWrite(pin3,HIGH);
  digitalWrite(pin4,HIGH);
}

void hello2(){
  sensor.setAddress(0x52);
  Serial.println(sensor.readReg(0x212),HEX);
  sensor.setAddress(Address2);
  sensor.writeReg(0x212,Address2);
  Serial.println(sensor.readReg(0x212),HEX);
  Serial.println();
  digitalWrite(pin2,LOW);
  digitalWrite(pin3,HIGH);
  digitalWrite(pin4,LOW);
  Serial.print("Ambient 2: ");
  Serial.print(sensor.readAmbientContinuous());
  if (sensor.timeoutOccurred()) { Serial.print(" TIMEOUT"); }
  Serial.print("\tRange 2: ");
  Serial.print(sensor.readRangeContinuousMillimeters());
  if (sensor.timeoutOccurred()) { Serial.print(" TIMEOUT"); }
  Serial.println();
  sensor.writeReg(0x212,0x52);
}

void hello3(){
  sensor.setAddress(0x52);
  Serial.println(sensor.readReg(0x212),HEX);
  sensor.setAddress(Address3);
  sensor.writeReg(0x212,Address3);
  Serial.println(sensor.readReg(0x212),HEX);
  Serial.println();
  digitalWrite(pin2,LOW);
  digitalWrite(pin3,LOW);
  digitalWrite(pin4,HIGH);
  Serial.print("Ambient 3: ");
  Serial.print(sensor.readAmbientContinuous());
  if (sensor.timeoutOccurred()) { Serial.print(" TIMEOUT"); }
  Serial.print("\tRange 3: ");
  Serial.print(sensor.readRangeContinuousMillimeters());
  if (sensor.timeoutOccurred()) { Serial.print(" TIMEOUT"); }
  Serial.println();
  sensor.writeReg(0x212,0x52);
}

Any help would be appreciated!

I'm trying to do the same thing. Did you get it to work by chance?

There are ICs that expand the I2C bus allowing you to have multiple devices with the same ID on (can't remember what they are called at the mo).

You can use an I2C multiplexer (TCA9548A). One I2C input can be output to one of the eight I2C outputs.
It has 8 configurable addresses, so you can connect 64 I2C devices with the same address by using 8 multiplexer chips.

You are using only one VL6180 object and then changing its address repeatedly. In your setup(), since all the sensors are enabled and have the same address, you're sending init commands to all of them; I'm not sure what will happen (multiple ACK/NACKs?), but it's probably not a good thing. Your hello() functions actually changes the address of all the sensors (twice?), if the commands even work, and then enables only one to read from. A host of undefined problems is expected.
To fix this, you have to do all the config and address changes in setup():

Before setup(), create 3 VL6180 objects: sensor1, sensor2, sensor3
In setup(), enable ONLY ONE sensor, and call all the sensor initialization commands on one of the objects you created (sensor1, maybe), as usual. Then call setAddress() on that sensor object to change its address to a unique one. This object is now tied to the physical sensor which has been enabled; all future operations related to that sensor, must be done on this object.
Then, disable this first sensor, and enable another and repeat the same steps as before on another object (sensor2), making sure to make each sensor's address unique. This way, you configure only one sensor at a time.
After configuring all three, you can now use their respective objects to get readings in loop().

I believe, if I have read this Multiple VL6180x in a design right, then you can change the I2C addresses of the sensors.  You need to hold all the sensors in reset then send it the change ID message.  I'm not sure if it is permanent or you have to do it each power up.
Does that help?


text:
How to produce rolling count per minute?
I have a counter attached to ISR:
void ISR_impulse() {
  CNT++;
}

and I want to calculate rolling count per minute with arbitrary update rate.
However I can only get it to update every minute:
void loop() {
  if (t - t0 > 60000) {
    CPM = CNT - CNT0;
    t0 = t;
    CNT0 = CNT;
  }

  t = millis();
  delay(100);
}

Requirement:

Rolling count with a window of 1 minute, and arbitrary update rate like 1 second ?
CPU has other tasks to do, which might take a significant amount of time.
SAMD21 has pulse period measurement in TC, but I have no idea how to set it up.

Partial solution one by edgar bonet:
  static uint8_t buf[60];
  static uint8_t idx;
  static uint32_t t0;
  static uint16_t CNT0;
  static uint8_t cpm;

  if (millis() - t0 >= 1000) {
    t0 = millis();
    uint16_t cps = CNT - CNT0;
    CNT0 = CNT;
    cpm += cps - buf[idx];
    buf[idx] = cps;
    if (++idx >= 60) idx = 0;
  }

How ever this only works if the loop code finishes in less than 1ms.

set up a FIFO buffer ... the ISR pushes decimal 60 into the buffer .... every second, a separate program routine decrements each of the values in the buffer by one, counts non-zero values and returns the count

While rewriting the code of my answer, you introduced a couple of errors: 1. By updating t0 with t0 = millis();, you make the tiny timing errors cumulative. If you update it with t0 += 1000; they are not cumulative: they only create a small amount of jitter, which is somewhat averaged-out by the subsequent running average. 2. By reading CNT twice with interrupts enabled, you create a race condition. If CNT is updated by the ISR between the two reads, you miss one pulse.

If you want to update every second a one minute running average, you
have no choice but store in memory the counts you got the previous
60 seconds. You store them in a ring buffer, so that every new
reading replaces the oldest one. Then, every second:

you add to the CPM count the number of counts you got this second
you subtract the number of counts you got on the second that just got
out of the sliding window.

I would implement that logic this way:
const uint32_t ONE_SECOND = 1000;

uint16_t counts_per_minute;
uint16_t previous_counts[60];
size_t counts_pos;

void loop() {
    static uint32_t previous_second;
    if (millis() - previous_second >= ONE_SECOND) {
        previous_second += ONE_SECOND;
        noInterrupts();
        uint16_t CNT_copy = CNT;
        interrupts();
        static uint16_t CNT_previous;
        uint16_t second_count = CNT_copy - CNT_previous;
        CNT_previous = CNT_copy;
        counts_per_minute += second_count - previous_counts[counts_pos];
        previous_counts[counts_pos] = second_count;
        if (++counts_pos >= 60) counts_pos = 0;
    }
}

Note that:

The timing variable is updated with previous_second += ONE_SECOND
rather than previous_second = now in order to avoid the accumulation
of small timing errors.
The counter that is updated in the ISR has to be read only once,
with interrupts disabled. Otherwise the interrupt may change it while
you are in the middle of reading it.

So it's a moving average with count-per-update-period as elements ? Wouldn't the noInterrupts() cause the counter to miss some counts ?

It would be perfect of you could add code to account for millis() < 60000 situation.

@7E10FC9A: You cannot meaningfully compute a one minute rolling average in less than one minute.

@7E10FC9A: noInterrupts() will not make you miss an interrupt. If an interrupt request fires while interrupts are disabled, it is put on hold and served right after the interrupts() call. Only if two instances of the same request fire within this period do you miss an interrupt. But since they are been disabled for less than half a microsecond, this could only happen with an interrupt rate way above what the Arduino can handle.

The code does not work if CPU has other tasks to do. The sampling interval is not guaranteed to be 1000ms.

@7E10FC9A: If you program in a non blocking fashion, your loop() should always execute very fast. If it takes more than a millisecond, you are most likely doing something wrong. With a very fast loop(), the inaccuracies will be tiny, and likely irrelevant. If your accuracy requirement is really so high that a fraction of a millisecond does matter, then program a timer to fire an interrupt every millisecond, and update counts_per_minute within the ISR.

MCU only have one thread, so it's difficult to make the loop code non-blocking. Let's say what would you do if there are other tasks that require CPU time >>1ms at random?

@7E10FC9A: In such a case I would use a timer interrupt. My point is that it is uncommon to actually need 1 ms of CPU time at once. If loop() takes more than 1 ms, it is more than likely that most of these CPU cycles are waisted delaying or busy-waiting for some event (i.e. “blocking”). Then you can make it non blocking by using a finite state machine and/or the technique shown in the Blink Without Delay tutorial.

Q doesn't say, but Is uint16_t large enough for the count/sec? //  If the CNT interrupt is accurate, then any errors introduced by the timing of the  samples are balanced by corresponding errors in the following second.    If the loop takes more than a second it could fall behind and overcount the minute, but short of that, the jitters should take care of themselves.

You need a First-In, First-Out buffer (FIFO) so that the oldest data drops off to make room for the newest. This is usually done with a circular buffer - an array whose beginning / end point change as data is added. (For comparison, the simplistic way is an array whose contents gets moved down (toward i = 0) each time you need to add a datum. But moving data is slow, so remembering where the oldest entry is, replacing it with the newest one, and updating the remembered oldest-data location gives a huge permormance improvement.
Secondly, you need to define how responsive your counter needs to be - how many updates per minute you'll need. That's the number of elements you need in the array.
Evaluating the immediately-passed minute's count is as simple as summing the array, which can be done without caring where the begin/end point is. Sum from 0 to N-1; the result will be the same.


text:
Writing a 32-bit register to 32 pins as fast as possible in Arduino Due
Problem:

I'm using Due's QDEC function to decode a 32bit quadrature encoder.
I need to pipe out the counter value as fast as possible to another instrument's DIO.
The rear strip is selected as digital output because it's easy to slap an IDC connector on it.

#define QA 2
#define QB 13
const unsigned int mask_QA = digitalPinToBitMask(QA);
const unsigned int mask_QB = digitalPinToBitMask(QB);

void setup() {
    Serial.begin(115200);
    delay(100);

    // QDEC block
    REG_PIOB_PDR = mask_QA;     // activate peripheral function
    REG_PIOB_ABSR |= mask_QA;   // choose peripheral option B
    REG_PIOB_PDR = mask_QB;
    REG_PIOB_ABSR |= mask_QB;

    REG_PMC_PCER0 = (1<<27);                                // activate clock for TC0 (PID27)
    REG_TC0_CMR0 = (1 << 0) | (1 << 2) | (1<<8) | (1<<10);  // config clock
    REG_TC0_BMR = (1<<9)|(1<<8)|(1<<12);                    // activate QDEC
    REG_TC0_CCR0 = 5;                                       // enable the clock and reset counter

    //PIO BLOCK
    // mask write, the rear strip of Arduino Due
    REG_PIOA_OWER = 0x0018c808; // A 7 14 15 19 20
    REG_PIOB_OWER = 0x04204000; // B 14 21 26
    REG_PIOC_OWER = 0x000FF3FE; // C 1-9 12-19
    REG_PIOD_OWER = 0x0000064F; // D 0 1 2 3 6 9 10
}
void loop() {

  // data write
  REG_PIOA_ODSR = REG_TC0_CV0;
  REG_PIOB_ODSR = REG_TC0_CV0;
  REG_PIOC_ODSR = REG_TC0_CV0;
  REG_PIOD_ODSR = REG_TC0_CV0;
}

This code is untested as I don't have access to the hardware right now.
Basically 4 bit masks (for PIO ABCD) are created to map the 32bit REG_TC0_CV0 onto the rear strip.

Requirement:

[Priority] As little delay as possible, every clock cycle matters.
[Secondary] Output bandwidth should match the update rate of REG_TC0_CV0, which I didn't manage to find in the manual. The output should also provide a latch for the receiving equipment to sync sampling.

Question:

Would disabling peripheral functions for all 32 pins on the rear strip interfere with the core functionality that this program depends on (timer/counter etc) ?
Are there other ways that can accomplish this faster ?
I would like to use the main CPU tread for serial interface. It is possible to attach the four ODSR writing instructions to a timer ISR so it does not interfere with void loop()?

Thanks in advance !

please post a link to the quadrature encoder .... it actually makes no sense that it would require a 32 bit interface

@jsotola The quadrature encoder is from a scientific-grade brushless linear motor. I don't know the exact part number but the linear motor has the precision of 20000 counts/mm, and the max travel of the motor is 220mm. So the top count is 4400000, which requires at least 23 bits. Also the output format of REG_TC0_CV0 is 32 bits.

Define as fast as possible? once per second, a 100,000,000 times a second, both are possible but there is a upper limit to what you can do with a processor, additional hardware may be needed. More Information Please?

@Gil Thanks for your interests in my question. I have updated the question to better define "fast".

@Gil 100MHz possible ? I thought the MCK is 84MHz. However that's irrelevant as the output should be attached to ISR for when REG_TC0_CV0 became available.


text:
Bluetooth data: how to handle these data?
I'm reading a BLE device and my api return me this struct
typedef struct {
  LGATTAddress bd_addr;
  int32_t rssi;
  uint8_t eir_len;
  uint8_t eir[256];
} LGATTDeviceInfo;

I try to print some eir_len and eir[256] and this is the result
  for(int i = 0; i < 255; i++)
  {
    Serial.print(info.eir[i], HEX);
  }
  Serial.println();

  Serial.print("Advertising data lenght: ");
  Serial.print(info.eir_len);
  Serial.println();

    21613FF4C0CE8E1B87D83CB43431A739F4496E0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
    Advertising data lenght: 23

    2167FF4C0102B00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
    Advertising data lenght: 11

    216320A0109524543414D3532474A5830313235315125005002A0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
    Advertising data lenght: 33

I cannot understand the relation between the air and the lenght: in the second example the response is 13 char but the lenght is 11. Why?
According to bluetooth specs..
The data is 240 octets and consists of a significant part and a non-significant part. The significant part contains a sequence of data structures. Each data structure shall have a length field of one octet, which contains the Length value, and a data field of Length octets. The first n octets of the data field contain the extended inquiry response (EIR) data type. The content of the remaining Length - n octets in the data field depends on the value of the EIR data type and is called the EIR data. The non-significant part extends the extended inquiry response to 240 octets and shall contain all-zero octets.

How can I parse the eir to obtain all the data? For example the name of the device and the manufacturer data?
update
Let's take for example this response
[LGATTC ino]dev address : [8:46:be:ca:2c:2] rssi [-63]
2 1 6 9 8 69 53 65 6E 73 6F 72 20 9 FF BE CA 2C 2 46 2 5F 5D 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
Advertising data lenght: 23

I try to convert the hex to string and this part 69 53 65 6E 73 6F 72 is the sensor name (iSensor).
This is a bluetooth sensor that change in this way
<be ca 2c 02 46 02 58 56> - > open
<be ca 2c 02 46 00 59 55> - > close
<be ca 2c 02 46 02 5a 58> - > open
<be ca 2c 02 46 00 5b 57> - > close
<be ca 2c 02 46 02 5c 5a> - > open
<be ca 2c 02 46 00 5d 59> - > close
<be ca 2c 02 46 02 5e 5c> - > open
<be ca 2c 02 46 00 5f 5b> - > close

These are the manufacturer data: the first part be ca 2c 02 is the unique identifier of the device, the 02/00 identify the status of the sensor...
By the way I negin to understand... I notice now the match between the lenght and the eir!
I must now extract the name in char, the status and the device code!
edit 2
I found the specs of my sensors...

Please show your code which is doing the printing.

@MarkSmith added!

Could you indicate what format you'd like this processed into, please?

Just the name is char and the manufacturer data

Do you know how arrays work in C(++)? And do you have a spec, please? I can show you code which works for this example, but with only one example I have no way to generalise it.

A little. But I'm a ruby developer and I'm studying C(++) for this project. By the way all the sensors are from the same manufacturer, and I will use a config file with the unique identifier of the sensors to filter the scanned devices...

OK, I've added code to decode the data. Rather than copying-and-pasting it, better to try to understand what it does and how it does it, and use it to write your own, because I've made VERY big assumptions which are probably not all correct.

I cannot understand the relation between the air and the lenght: in the second example the response is 13 char but the lenght is 11. Why?

The hex numbers may be one or two digits long.  The way the values are being printed does not enable you to discern between 1 2 3, 12 3 and 1 23. Try this:
for(int i = 0; i < 255; i++)
{
  Serial.print(info.eir[i], HEX);
  Serial.print(" ");
}

(Someone already told you this.)

How can I parse the eir to obtain all the data? For example the name of the device and the manufacturer data?

This works for the only example of the data you have given.  If I have guessed correctly how further data will follow, it'll work for them too.  (If I haven't, it won't.)  I have assumed that the name always starts in the same place, ends with a space, three bytes of stuff we don't care about, and that the data is groups of 8 bytes.  It's very likely that some of the other bytes give details of the data to follow, but with only one example and no spec, it's basically impossible to tell.
// Let's assume the sensor name always starts at element 5...
char *sensorName = &(info.eir[5]);
// ...and ends on a 0x20 (space) - which is probably a risky assumption
char *end = strchr(sensorName, ' ');
if (end)
{
    *end = '\0';
    // Sensor name is now in sensorName

    // Let's assume the data starts exactly 4 bytes after the end of the name
    uint8_t *dataItemStart = (uint8_t*)(end + 3);
    uint8_t *dataEnd = info.eir + info.eir_len - 1;
    while(dataItemStart < dataEnd)
    {
        // We have a data item here, as 'dataItemStart'.
        // You can get bytes within it using, for example
        //   dataItemStart[5]
        // to get the 6th item (the 00 or 02 in your examples)

        // Each data item is 8 bytes long, so the next one starts 8 bytes later
        dataItemStart += 8;
    }
}

thank you, I notie now the Paul response! I begin to understand... I add the data I know from a sensor I know!

Thank you so much. I also find the specs of the sensors (I edited the question). I understand that I have 0x08 and then the name (with the space at the end) and 0xFF and then the data. I will try to adapt the code.

That makes much more sense now, with the spec. All the concepts you need should be there in the code above, though.  Feel free to accept and optionally upvote the answer if it helped :-)


text:
Input PUK code, when requested
Problem:
I'm working with a GPRS module (the same as in the Arduino GSMShield). In some cases the PUK code is requested, and the PIN is thus locked. For this I wrote some code (which can be seen under "Software"). This code is based on the documentation of "GSM PIN Management". The only problem is that the module is telling us that both the PIN & PUK code is locked. The tutorials, however, does not provide an example how we should resolve this issue from the Arduino itself.
EDIT: When the SIM card is inserted in a smartphone. The PUK code is requested. When the PUK code is provided (and a new PIN) the SIM card is back to normal. But adding the PUK code via the GSM lib. doesn't really work, in contrast to using a smartphone to unlock the PIN code.
Question:

Does anybody have an idea how to resolve this issue? And if it can be done?

Hardware:

Atmega328p
Quectel M95 (as GPRS module)

Software:
PINManager.begin();
int pin_query = PINManager.isPIN();
Serial.print(F("Pin Query is: ")); //output: -2
Serial.println(pin_query);
if(pin_query == -1)
{
  #ifdef DEBUG
    Serial.println(F("PUK is requested"));
  #endif

  if(PINManager.checkPUK(PUK_NUMBER, PIN_NUMBER_CORRECT) == 0)
  {
    PINManager.setPINUsed(true); // I also think this must by "false". Both things were tested, none of them worked.

  }
}

If you enter the wrong PUK code 10 times or more, then you will need a new SIM card.

That's not the case. Because when the SIM is inserted in a smartphone/gsm, the PUK is requested. When adding the PUK code and a new PIN code, the SIM works fine. See the EDIT in the post.

I've resolved the issue by using AT commands instead of the GSM library provided through Arduino.
if(sendGPRSCommand(F("AT+CPIN?"),100).equals("AT+CPIN+CPIN:SIMPUKOK")){
    Serial.println(F("PUK is requested, entering it now"));
    String cmd = "AT+CPIN=\"";
    cmd.concat(PUK_NUMBER);
    cmd.concat("\",\"");
    cmd.concat(PIN_NUMBER);
    cmd.concat("\"");
    sendGPRSCommand(cmd,100);
  }

This code checks if the PUK code is requested, this is the case when the pin_query is -1 or -2 (see question). When the PUK code is requested the new PIN (which is still the same pin as the old one) is given in combination with the PUK code.
The AT commands were found in this manual.


text:
Multiple SPI reads slows down read time dramatically
I have a two channel 24bit ADC(LTC2402- http://cds.linear.com/docs/en/datasheet/24012f.pdf) that I am communicating with via Arduino Leonardo(Leonardo because it was free!). If I attempt to do multiple reads the SPI becomes very slow while if I do a single read the time to send is what is expected. I have have integrated with python and timed the different transactions. A single read takes around 170ms( this is for both channels and the datasheet of the ADC indicates about 65ms per conversion(table 3 arduino as external sck etc.)) BUT if I do 5 reads the time taken is about 1.5s(expected about 0.65s) 10 reads take about 3s and 20 about 6.5s. Doing no ADC conversions and just serial comm to python is less than 2ms.
The relevant python code is as follows:
def getdata(ser,code):#ser is the arduino that has been connected, code is for writting to arduino
    ser.write(code)
    ch0=float(ser.readline().decode()[:-2])
    ch1=float(ser.readline().decode()[:-2])
    return ch0,ch1

code='1'
code=code.encode()

a=datetime.datetime.now()
ch0,ch1=getdata(ser,code)
b=datetime.datetime.now()
print(b-a)

The arduino code is as follows. The code has been simplified to just the necessary byte reads from the ADC, all other code has been removed to ensure the delays are coming from the SPI.transfer(0x00). The full code retrieves 4 bytes per channel and converts this to voltage and returns these values.
#include <SPI.h>

const int ltcs = 3; //active low ADC enable

float ch0=0.0;
float ch1=0.0;
byte b0;

void setup() {
SPI.begin();
SPI.beginTransaction(SPISettings(200000, MSBFIRST, SPI_MODE0));

Serial.begin(9600); // set the baud rate

pinMode(ltcs, OUTPUT);
digitalWrite(ltcs, LOW);
}

void loop() {
if(Serial.available()){

   int data = Serial.read() - '0';
   if(data>0){

   getdata2(ch0,ch1);
    //getdata2(ch0,ch1); //run multiple getdata2 to test multiple conversions
   //getdata2(ch0,ch1);
    //getdata2(ch0,ch1);
   //getdata2(ch0,ch1);

    Serial.println(0.2);
    Serial.println(0.4);

  }
  }
  }

 void getdata2(float &ch0, float &ch1) {
   ch0 = 0.0;
   ch1 = 0.0;

   for (int i = 0; i < 2; i++) { //Do twice to retrieve both Channels
     while (digitalRead(MISO) == HIGH) {
     }

       b0 = SPI.transfer(0x00);
       b0 = SPI.transfer(0x00);
       b0 = SPI.transfer(0x00);
       b0 = SPI.transfer(0x00);
   }
   }

Can anyone help me? I have tried different SPISettings with no change. Interestingly I also find that the Baud rate does not change either.
Thanks for the help if any

Why are you reading from MISO? Why are you ignoring b0? You don't seem to be changing ch except to set it to zero. I don't see what getdata2 achieves except to slow things down.

The time isn't increasing exponentially. 5 reads take 1.5s, 10 reads take 3s and 20 reads takes 6s. That's a linear increase.

@NickGammon - Hi, MISO is just to see when data is ready. I'm only ignoring b0 for the example code. The actual code reads byte by byte and reconstructs to the 24bit which is then translated to voltage. In the actual code ch is the translated voltage as a float. So in short getdata2 is the function that recieves 4 bytes from the ADC and translates to voltage. I may have been a little dramatic by saying the time increases exponentially but it does double after a few reads. Hope that clears it up

@NickGammon- The Code I included here was to ensure that no other code was causing delays. This is the bare minimum needed to receive data from the ADC

I can only see one call to getdata2 call in the above code. Can you please show the actual code that is slow?

Try removing all references to serial comms. Just call getdata2 in a loop, and toggle an LED each time it finishes. That will demonstrate whether the issue is with SPI or the way you are communicating with your PC.

@NickGammon, did you not see the commented out calls to getdata2? It's as simple as calling getdata2 multiple times... I used this exact code and timed for each added getdata2 call

@NickGammon, I did something similar I commented all the b0=SPI.transfers but left the serial comm and wait for MOSI etc and that completed in under 2ms.

Why do you have a loop of 2 iterations when reading the ADC? Why the delayMicroseconds(1)? After doing while (digitalRead(MISO) == HIGH) { } you hardly need to test if MISO is LOW, right? What else would it be?

@NickGammon- loop is to read both channels @ 4 bytes each. BUT you're right, no need for the delay and test MISO LOW but they have no effect on time. The delay was there initially to see if a short delay would prevent the much longer one which it didn't.

MISO will be changing rapidly. A second test will not be helpful. digitalRead is quite slow. You might be better off connecting SDO (MISO) to an interrupt pin, if you want to know when the conversion is ready. Even your while loop (with digitalRead inside it) will probably execute too slowly.

Interestingly I also find that the Baud rate does not change either. - on the Leonardo serial comms goes through the USB interface, and changing the baud rate in the sketch does not affect the output rate.

@NickGammon- I tested the MISO response by running getdata2 multiple times but commented out all b0=SPI.transfer() and even if I run 5 or more times the time to complete is <2ms. So the delay is not due to the digitalRead or the while loop.

There is no way that SPI.transfer() can slow down. It's impossible. Do what I suggested and remove all serial comms.

@NickGammon- Sorry Solved it. It wasn't a software issue after all... It was me being dumb and incorrectly assuming the external oscillator frequency. Thanks for the time and effort though.

I found the error. Unfortunately I was so busy blaming the code and assuming it was my lack of arduino knowledge that I forgot to check the hardware specs. I thought I was using the maximum external oscillator frequency(f_EOSC) of 300KHz, but in fact was using the 50Hz internal oscillator frequency with an external f_sck from the arduino. This means that the conversions where in fact running at expected times. The thing that threw me off was that the first reading was much faster than the rest. This was most likely because at first read I only had to wait for one channel conversion as the other was already done before I request the data and so the first readings wait time is only as long as a single channels conversion. I would need to implement a 300KHz external clk if I want faster conversion speeds. Thanks for the help for those who tried:)

You probably want to take a look at the datasheet and work on one routine that returns adc results from a channel selected by the user. The typical process is to read the register until EOC is asserted (_EOC is low).
and you would go from there.

@dannyf- Can you please elaborate? I have the ADC correctly returning values so I am unsure what you're referring to. It's literally just the timing.

@dannyf- Nevermind. I solved it. I was actually already doing what you suggested. The /EOC is implement on the SDO/MISO channel just before data conversion. Thanks though.


text:
Can't get actual output when, both input logic is high
I want
When,

light=0, ir=0 then output will pin 8 high & pin 12 low.
light=0, ir=1 then output will pin 8 high & pin 12 high.
light=1, ir=0 then output will pin 8 low & pin 12 low.
light=1, ir=1 then output will pin 8 low & pin 12 low (This statement
does not work).

Please find the code & suggest me, if any modification is needed.
void setup() {

    pinMode(8,OUTPUT); //logic output.
    pinMode(12,OUTPUT); //logic output.
    pinMode(2, INPUT); //value input.
    pinMode(4, INPUT); //value input.

    Serial.begin(9600);
}

void loop() {

    int light = digitalRead(2); //value input.
    int ir = digitalRead(4); //value input.

    if (light == LOW && ir == LOW)
    {

      digitalWrite(8, HIGH);
      digitalWrite(12, LOW);
      delay(2000);

    }

    if (light == LOW && ir == HIGH)
    {

      digitalWrite(8, HIGH);
      digitalWrite(12, HIGH);
      delay(2000);

    }

    if (light == HIGH && ir == LOW)
    {

      digitalWrite(8, LOW);
      digitalWrite(12, LOW);
      delay(2000);

    }

    if (light == HIGH && ir == HIGH) //This condition does not work.
    {

      digitalWrite(8, LOW);
      digitalWrite(12, LOW);
      delay(2000);

    }

    digitalWrite(8, LOW);
    digitalWrite(12, LOW);
    delay(2000);

}

Please format your code using a code block (see https://meta.stackexchange.com/questions/22186/how-do-i-format-my-code-blocks). I don't know why your code does not work like you intended, but the last two IF statements (including the one that does not work) are the same for ir being LOW or HIGH, so you can just as well combine them into one, for example: if (light == HIGH) { digitalWrite(8,LOW); digitalWrite(12,LOW); delay (2000); }. Or maybe that isn't what you intended and that's where the error in your code is.

Also, it would be helpful to explain what your code is supposed to do and what hardware it is connected to.

Here is two input & two output.
I want,
if light=0, ir=0 then output will pin 8 high & pin 12 low.
if light=0, ir=1 then output will pin 8 high & pin 12 high.
Otherwise output will,
pin 8 low & pin 12 low.

print some debug messages so you can see what‘s going on.

put the delay(2000); after all of the if statements

digitalWrite(8,LOW); digitalWrite(12,LOW);

You can simplify your requirements somewhat by splitting your inputs up.

light=0, ir=0 then output will pin 8 high & pin 12 low.
light=0, ir=1 then output will pin 8 high & pin 12 high.

If light is 0 then pin 8 is high. AND ir is echoed to pin 12.

light=1, ir=0 then output will pin 8 low & pin 12 low.
light=1, ir=1 then output will pin 8 low & pin 12 low

If light is 1 then both pins 8 and 12 are low, and you don't care what ir does, since it doesn't have any effect on the outputs.
So your structure could look more like:
if (light == 0) {
    digitalWrite(8, HIGH); // 8 will always be high with light == 0
    digitalWrite(12, ir); // echo the ir value to pin 12
} else {
    digitalWrite(8, LOW); // if light is 1 then everything
    digitalWrite(12, LOW);// is low regardless of ir.
}

Note this is not an answer to the question (I don't see any problem initially), but to clean the code it might help to debug it (using print statements as Sim Son suggests).
Instead of all the if statements, check when pin 8 and pin 12 needs to be HIGH:
 pin 8:  (light == LOW && ir == LOW)
 pin 12: (light == LOW && ir == LOW)  or (light == LOW && ir == HIGH)

For pin 12, the condition can be rewritten as
 pin 12: (light == LOW) || (ir == LOW or ir == HIGH)

which is equal to
 pin 12: light == LOW

So now you can change the code from the loop function to:
void loop()
{
   digitalWrite(8 , (light == LOW && ir == LOW) ? HIGH : LOW);
   digitalWrite(12, (light == LOW             ) ? HIGH : LOW);
   delay(2000);

   digitalWrite(8, LOW);
   digitalWrite(12, LOW);
   delay(2000);

}
the x ? : z statements means: if x is true, do y, else z.
The last three statements are fixed (copied from your code).
Now we can even further reduce it, by removing the duplicated code
void loop()
{
   processLeds((light == LOW && ir == LOW), (light == LOW));
   processLeds(False                      , False         );
}

void processLeds(int conditionLed8, int conditionLed12)
{
    digitalWrite( 8, conditionLed8  ? HIGH : LOW);
    digitalWrite(12, conditionLed12 ? HIGH : LOW);
    delay(2000);
}

You pass the condition when led 8 and 12 have to be high or log to a function, which sets the LEDs.
Now you can also use much less print statements for finding your problem.


text:
GPS Ublox Neo 6m issue with arduino UNO
I started working on the Arduino UNO with GPS Ublox Neo 6m. I connect GPS with arduino based on the schematic diagram as well as the script. It didn't display any data in the serial monitor even though it blinks and one more I did outside the building. I don't know what is causing it not to display any data.
#include <TinyGPS++.h>
#include <SoftwareSerial.h>

static const int RXPin = 4, TXPin = 3;
static const uint32_t GPSBaud = 9600;

// The TinyGPS++ object
TinyGPSPlus gps;

// The serial connection to the GPS device
SoftwareSerial ss(RXPin, TXPin);

void setup(){
  Serial.begin(9600);
  ss.begin(GPSBaud);
}

void loop(){
  // This sketch displays information every time a new sentence is correctly encoded.
  while (ss.available() > 0){
    gps.encode(ss.read());
    if (gps.location.isUpdated()){
      Serial.print("Latitude= ");
      Serial.print(gps.location.lat(), 6);
      Serial.print(" Longitude= ");
      Serial.println(gps.location.lng(), 6);
    }
  }
}

Did you properly connect the GPS module to VCC and GND and connected the TX of the GPS to the Arduino RX and vice versa? Also note that in my experience, many (if not most) cheap "Ublox" Neo 6M's sold are actually counterfeit and are of dubious quality, taking a very long time to get a first (or even subsequent) fix and not supporting many features of real Ublox GPS modules.


text:
arduino cont down timer in minutes with out using delay
i have one code with delay pleas help me remove the delay i will using this code in air cooler with some sensors delay stop working sensors
void startCycle(int cycleTimeInMinutes, const char *type) {
  lcd.clear();
  const char *topRow[1] = { type };
  printTopRow(topRow, 1, 5);

  cool1(true);

  for (int cycleTimeLeft = cycleTimeInMinutes; cycleTimeLeft > 0; cycleTimeLeft--) {
    char buffer[2];
    const char *bottomRow[3] = { itoa(cycleTimeLeft, buffer, 10), "Minutes"};
    printBottomRow(bottomRow, 3, 6);
    delay(60000);
  }
  cool1(false);
}

Check this sketch: https://www.arduino.cc/en/Tutorial/BlinkWithoutDelay


text:
node mcu disconnect from mqtt server
/*
    Basic ESP8266 MQTT example

    This sketch demonstrates the capabilities of the pubsub library in combination
    with the ESP8266 board/library.

    It connects to an MQTT server then:
    - publishes "hello world" to the topic "outTopic" every two seconds
    - subscribes to the topic "inTopic", printing out any messages
    it receives. NB - it assumes the received payloads are strings not binary
    - If the first character of the topic "inTopic" is an 1, switch ON the ESP Led,
    else switch it off

    It will reconnect to the server if the connection is lost using a blocking
    reconnect function. See the 'mqtt_reconnect_nonblocking' example for how to
    achieve the same result without blocking the main loop.

    To install the ESP8266 board, (using Arduino 1.6.4+):
    - Add the following 3rd party board manager under "File -> Preferences -> Additional Boards Manager URLs":
    http://arduino.esp8266.com/stable/package_esp8266com_index.json
    - Open the "Tools -> Board -> Board Manager" and click install for the ESP8266"
    - Select your ESP8266 in "Tools -> Board"

*/

#include <ESP8266WiFi.h>
#include <PubSubClient.h>

// Update these with values suitable for your network.

const char* ssid = "SepehrNet";
const char* password = "orangecoffee";
const char* mqtt_server = "test.mosquitto.org";

WiFiClient espClient;
PubSubClient client(espClient);
long lastMsg = 0;
char msg[50];
int value = 0;

void setup_wifi() {

    delay(10);
    // We start by connecting to a WiFi network
    Serial.println();
    Serial.print("Connecting to ");
    Serial.println(ssid);

    WiFi.begin(ssid, password);

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

    randomSeed(micros());

    Serial.println("");
    Serial.println("WiFi connected");
    Serial.println("IP address: ");
    Serial.println(WiFi.localIP());
}

void callback(char* topic, byte* payload, unsigned int length) {
    Serial.print("Message arrived [");
    Serial.print(topic);
    Serial.print("] ");
    for (int i = 0; i < length; i++) {
        Serial.print((char)payload[i]);
    }
    Serial.println();

    // Switch on the LED if an 1 was received as first character
    if ((char)payload[0] == '1') {
        digitalWrite(BUILTIN_LED, LOW);   // Turn the LED on (Note that LOW is the voltage level
        // but actually the LED is on; this is because
        // it is active low on the ESP-01)
    } else {
        digitalWrite(BUILTIN_LED, HIGH);  // Turn the LED off by making the voltage HIGH
    }

}

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

void setup() {
    pinMode(BUILTIN_LED, OUTPUT);     // Initialize the BUILTIN_LED pin as an output
    Serial.begin(115200);
    setup_wifi();
    client.setServer(mqtt_server, 1883);
    client.setCallback(callback);
}

void loop() {

    if (!client.connected()) {
        reconnect();
    }
    client.loop();

    long now = millis();
    if (now - lastMsg > 2000) {
        lastMsg = now;
        ++value;
        snprintf (msg, 50, "hello world #%ld", value);
        Serial.print("Publish message: ");
        Serial.println(msg);
        client.publish("outTopic", msg);
    }
}

I'm beginner at IOT and I'm using NodeMcu ESP8266 board and I want to control it with Arduino IDE so I install everything necessary and also using PubSubClient library for that. I used example file of PubSub in arduino. The NodeMcu first connects to internet and after a second disconnects.
I also switched the server(I don't know internet connection) from home modem to my mobile internet but it doesn't worked. I installed MQTT android application and want to connect to test server"test.mosquitto.org" and publish a meassage from NodeMcu to MQTT dashboard on my android mobile.
what is the problem with this standard sample code?

I don't know how to add my sketch in a properly way. does anyone know?

One line: three back-apostrophes. Then paste your sketch. Then three back-apostrophes again on another line.

FYI: Return code -4 means: MQTT_CONNECTION_TIMEOUT - the server didn't respond within the keepalive time. It looks like your NodeMCU connects to your Wifi but cannot reach the MQTT broker. Can you ping test.mosquitto.org from your PC?

@jsotola, this looks like the mqtt_esp8266 example sketch that's part of the PubSubClient library

@sepehr, Your code connected and ran without problems on one of my NodeMCUs (with my Wifi credentials). The problem is not in your code.

@StarCat yes I can ping. I could load the web page on test.mosquitto.org.so what do you think about the problem? is that my internet connection? what should I do for debugging?

Does your NodeMCU actually have access to internet? Check with an NTP client or HTTP client example sketch. You could also try one of the other public mqtt brokers for testing You can choose one from this list.

@StarCat thanks. I tried another testing mqtt broker and it worked.


text:
Level shifting 5V <-> 3.3V
My main goal is to use connect the HC-SR04 ultrasonic sensor with ESP8266.
Problem is, HC-SR04 works with 5V while the ESP8266 works with 3.3V
In order to solve this, idea would be to use a logical level converter.
I bought some of this 3.3V 5V TTL Bi-directional Logic Level Converter(s) a good while ago, and thought they would fit best for this project.
Here's my setup

5V from arduino
3.3V from digital power supply
GND connected together
Nothing connected to TX0 (HV side)
Voltmeter connected to TX1 (LV side), still getting a 3.3V

Here's a closer look at the breadboard connections

Am I doing something wrong ? Any suggestions would be appreciated !

Are you sure you connected it correctly? The description on the seller's site is not clear at all, and at least a bit ambiguous. I'm also not sure if these boards are really bidirectional as the markings seem to indicate Inputs (I) and Outputs (O). What do you see at RXO (Receive-Out?) on the low side if you connect, for example, the RXI (Receive-In?) on the high side to 0V or 5V? It would be very nice if these cheap boards were properly documented...

I'm not sure at all. I get 2.5V on RX0 if I connect RXI to 5V, and 0V if I connect RX1 to GND. I agree with the documentation, that's why I was hoping someone here might know more about them

Edit: Forget the post above if you just want to know how your board is working. Your board is a retired Spurkfun product - clone.
Here you can see the schematics and all info about your board:
https://learn.sparkfun.com/tutorials/retired---using-the-logic-level-converter
Original post:
The module you got, use the BSS138 MOSFET.
The circuit is easy, and how @Majenko said, it has just 2 pullups:
See https://electronics.stackexchange.com/questions/367052/replace-bss138-with-ao3400a-in-level-shifter-circuit

But this board is really strange: what means TX0, TX1, RX0, RX1 on the same MOSFET? It is better if you can measure it to be sure how to connect the sensor to the TX.
But there is a better way to solve it: Since you just have 1 input to your ESP, why not use 2 resistors?
5V--- 1k --- 2k --- GND
And connect the ESP input between the 2 resistors? It is even faster, because the MOSFET need up to 20ns to change state.

Thanks for making some "light". I tried all possible combinations with the module and still can't go from 3.3V -> 5V or the other way around. No wonder it's retired, also name starts with BS..
On the ESP I'll need two pins with the ultrasonic sensor. 1 as input and 1 as output. I'll try what you were saying above with the input pin but how should I go about the output ?

The board was made for a serial converter from 5V to 3.3V. This is the reason for RO and RI, or TO and TI. Since in the circuit, the Rx use just 2 resistors, you have to use the T0 and TI. So, put the Esp32 pin to TI, and your sensor input to TO. And invert VL with VH, if you have still 3V, since you want convert from 3V to 5V but the circuit was made to convert 5V to 3.3V. It should not be a problem if you do not use the middle part of this board.

I'm a bit worried that if I wire the ESP and sensor with the module and test it like that, it might damage them, if the module doesn't work as expected (eg. draws too much current). Would there be an "easy" way to check 3.3V to 5V, without being the possibility of damaging something ? The 5V to 3.3V works with the resistors

Yes, I know what you mean. An easy way to check is to apply a 3.3V to an XI (RI or TI) and see what you get on the output (RI goes to RO and TI goes to TO). How you connected the board is right (GND, LV to 3.3V and HV to 5V), I would just apply a 3.3V to both inputs: RI and TI, and check if you can measure 5V on RO or TO. If you measure still 3.3V, you have to set the 3.3V on RO and TO or invert LV and LH voltages. Just test it without the sensor or Arduino connected on this board.

Check this out:
https://learn.sparkfun.com/tutorials/bi-directional-logic-level-converter-hookup-guide/all
This article gives a comprehensive explanation about the bi-directional logic level converter and it's connection in a circuit.

No, you're not doing anything wrong.  Those simple MOSFET level shifters work by having both sides pulled up by resistors to their respective power supplies. When one side gets pulled low by a digital signal that LOW is mirrored to the other side of the MOSFET.
If you connect your TX0 pin to GND you will see the TX1 pin go to 0V.

Tried it, but it's not working. Also the current on the digital power supply increased to 0.7A - https://i.imgur.com/UG5dj6R.png

It might be only a one-way then.  I notice on closer inspection that it's not TX0 and TX1 bit TXI and TXO. That's Input and Output. For 5V->3.3v you should use RXI and RXO for 5V (I) and 3.3V (O), which just uses a simple voltage divider.


text:
Where does the 5v Output power on the Arduino uno come from?
I am wondering where the extra 5v output power on the Arduino uno come from. Is it directly from the atmega328 microcontroller or from the external power source (usb or 9v battery). Thanks.

If you are connected to USB then it comes direct from the USB port's 5V.
If you have an external power supply connected (either to the barrel jack or to the VIN pin) then it comes from the onboard 5V regulator.
The only thing that ever comes from the ATMega chip is digital signals.


text:
MD5 of File doesnot match data in flash Error with ESP32 S3
I am getting the fatal error MD5 of file not match data in flash. Below is the output of upload.
[1/5] cmd.exe /C "cd /D D:\Users\INOMETRICS\espressif\workspace\blink\build\esp-idf\esptool_py && python D:/Espressif/frameworks/esp-idf-v4.4/components/partition_table/check_sizes.py --offset 0x8000 partition --type app D:/Users/INOMETRICS/espressif/workspace/blink/build/partition_table/partition-table.bin D:/Users/INOMETRICS/espressif/workspace/blink/build/blink.bin"
blink.bin binary size 0x31340 bytes. Smallest app partition is 0x100000 bytes. 0xcecc0 bytes (81%) free.
[2/5] Performing build step for 'bootloader'
[1/1] cmd.exe /C "cd /D D:\Users\INOMETRICS\espressif\workspace\blink\build\bootloader\esp-idf\esptool_py && python D:/Espressif/frameworks/esp-idf-v4.4/components/partition_table/check_sizes.py --offset 0x8000 bootloader 0x0 D:/Users/INOMETRICS/espressif/workspace/blink/build/bootloader/bootloader.bin"
Bootloader binary size 0x5180 bytes. 0x2e80 bytes (36%) free.
[2/3] cmd.exe /C "cd /D D:\Espressif\frameworks\esp-idf-v4.4\components\esptool_py && D:\Espressif\tools\cmake\3.20.3\bin\cmake.exe -D IDF_PATH="D:/Espressif/frameworks/esp-idf-v4.4" -D SERIAL_TOOL="python D:/Espressif/frameworks/esp-idf-v4.4/components/esptool_py/esptool/esptool.py --chip esp32s3" -D SERIAL_TOOL_ARGS="--before=default_reset --after=hard_reset write_flash @flash_args" -D WORKING_DIRECTORY="D:/Users/INOMETRICS/espressif/workspace/blink/build" -P D:/Espressif/frameworks/esp-idf-v4.4/components/esptool_py/run_serial_tool.cmake"
esptool.py esp32s3 -p COM8 -b 460800 --before=default_reset --after=hard_reset write_flash --flash_mode dio --flash_freq 80m --flash_size 2MB 0x0 bootloader/bootloader.bin 0x10000 blink.bin 0x8000 partition_table/partition-table.bin
esptool.py v3.2-dev
Serial port COM8
Connecting...
Chip is ESP32-S3
Features: WiFi, BLE
Crystal is 40MHz
MAC: 70:04:1d:be:ab:74
Uploading stub...
Running stub...
Stub running...
Changing baud rate to 460800
Changed.
Configuring flash size...
Flash will be erased from 0x00000000 to 0x00005fff...
Flash will be erased from 0x00010000 to 0x00041fff...
Flash will be erased from 0x00008000 to 0x00008fff...
Compressed 20864 bytes to 13002...
Writing at 0x00000000... (100 %)
Wrote 20864 bytes (13002 compressed) at 0x00000000 in 0.1 seconds (effective 1284.4 kbit/s)...
File  md5: 1d4bc050825217f8434a2cfd167894cd
Flash md5: 1b32e380d00eb036ce18a632dedbe04d
MD5 of 0xFF is b145c0e952abec491d69c8c5f8ac47c4

A fatal error occurred: MD5 of file does not match data in flash!
CMake Error at run_serial_tool.cmake:56 (message):
  python
  D:/Espressif/frameworks/esp-idf-v4.4/components/esptool_py/esptool/esptool.py
  --chip esp32s3 failed

I am getting the same error while uploading with esp-idf and Arduino ide or platformio.
How could i solve the issue.
Regards

Yes, I have managed to get it working now, the issue encountered was with the strapping pins. Specifically, Pin 45 of ESP32S3 is responsible for configuring VDD_SPI_FLASH. To ensure it operates at 3.3V, the pin should be connected to the ground. Otherwise, it will function at 1.8V, which might cause problems with the Flash functionality.
Fortunately, this can also be resolved by burning some EFUSES using the espefuse.py tool, which comes along with esptool.py. All you need to do is run the command: espefuse.py set_flash_voltage <voltage> (where voltage can be either 3.3V or 1.8V or OFF). For more details, you can visit: link to the official documentation.


text:
`time.sleep` in python script reading serial output causes erratic behavior
I am attempting to control the position of my computer's cursor using a potentiometer hooked up to my arduino nano. The arduino is running the following code:
int potPin = 3;    // select the input pin for the potentiometer
int val = 0;       // variable to store the value coming from the sensor

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

void loop() {
  val = analogRead(potPin);    // read the value from the sensor
  Serial.println(val);
}

When I ran the following python script, it worked properly and the sensor values were printing out in my terminal.
import serial
import pyautogui

ser = serial.Serial("/dev/cu.usbserial-141220", 9600, timeout=0.1)

while True:
    data = ser.readline().decode("UTF-8").strip()
    if data:
        print(data)

However, when I added a small time delay in the while loop, the output would either get stuck on a single value or take multiple seconds to reflect a change to the potentiometer.
import serial
import pyautogui
import time

ser = serial.Serial("/dev/cu.usbserial-141220", 9600, timeout=0.1)

while True:
    data = ser.readline().decode("UTF-8").strip()
    if data:
        print(data)
    time.sleep(0.01)

I'd appreciate any help fixing this issue.

What is a small delay for you? 100ms? You are sending the values as fast as the Arduino can.

@chrisl the issue happens even with a delay in the python while loop of 10ms. I added the code with the loop to my question.

@ManavBokinala, Like chrisl said, you're sending as fast as you can.  What keeps approximately 9.6 characters per iteration from piling up in the host's inbound buffer?

You may find printing ser.in_waiting inside your loop enlightening.

@timemage Thank you so much, this solved my problem! I'm new to all of this, so I did not understand the concept of the inbound buffer. Your comment made things clear for me. I really appreciate it.

Thanks to chrisl and timemage's comments, I figured out the issue: the Arduino was sending the data too fast and the bytes were piling up in the computer's inbound buffer. I solved this by adding a delay to the loop() function of the Arduino code.


text:
Send Photo with Arduino Uno
I'm new at Arduino projects. I googled but I couldn't quite get an answer.
I've got:

Arduino Uno R3 clone
4 pin push button
3 color RGB LED Module
HC06 Bluetooth-Serial Module Card
Arduino PIC Camera Module OV7670

In my project, when the button is pushed, the Arduino takes a photo from the camera module and sends it with an HC06 Bluetooth Module to an Android device. And it receives the answer to turn on the Led green or red.
The main problem is how can I capture the photo and send it with bluetooth? I can handle the Android side.
EDIT 1
I reviewed that code: OV7670 FIFO on GitHub.
In the "Take Picture" method, I understand that the OV7670 continuously grabs frames and stores them in itself. I send it a signal to load a frame on Data Out pins. (D0-7) It loads first 8 bytes on the pins and in Arduinoo, in the for loops for height, width and byte for each pixels, I read in it from D0-7 and send a signal for next byte array.
But I can't understand how to connect the OV7670 to the Arduino. In code, there are conts called WRST, RRST, WEN, VSYNC and RCLK. On the OV7670 I've got SIOC, SIOD, VSYNC, HREF, PCLK, XCLK, D0-7, RESET and PWDN pins. How can I connect these pins like in the github link?
By the way here is my OV7670, I read there are different versions of OV7670:

Ok, so in this project I can see three main topics: 1) acquire a photo from the OV7670, 2) send data through the bluetooth module, 3) what is the best way to acquire and transfer a big image with poor hardware. So, what is your questoin related to? Did you already perform some of these steps?

Button, connectin Android and receiving-transmittin data and turn leds is okay. I cannot connect Arduino and OV7670 and can not capture frame (photo) with it.

It doesn't seem that that library is the correct one for you, since the signals are quite different. Maybe you can see what are the differences, but then you should integrate them by reading the datasheet of the OV7670 module..

Okay, there are differences between code and datasheet. But how can I use this card with Arduino? This is the subject of my question..

I have looked into something very similar and I think the reason you are finding it difficult to find information is you are viewing the full system.  Break it down into smaller chunks and you will get more chance of finding a match.  So lets look at the camera and then the rest of it.
I think that the reason you can't get an answer for this is that you can't do what you want with what you have.  My research seems to say that the OVO7670 camera needs a separate micro processor and 'special' RAM to work (can't remember what is special about the RAM at the moment).  There is a board that does this called a 'PIXY', but its not cheap.
On the plus side, connecting an Arduino to Android via blue tooth should be quite simple there should be lots of examples on how to set up the Arduino side.  You then need to define to convey your messages between your server an client and I know you aren't asking how to turn a LED on and off from an Arduino. (If you are please see the Example Blink).
Hope that helps
EDIT
I think you should have 18 pins on you OV7670.

3v3 - 3.3v
Gnd - Ground
SIOC - Input - I2C Clock
SIOD - I/O - I2C Data
VSYNC - Output - Vertical Synch
HREF - Output - Horizontal Synch
PCLK - Output - Pixel Clock
XCLK - Input - System Clock
D7 - Output - Data bit 7 (MSB)
D6 - Output - Data bit 6
D5 - Output - Data bit 5
D4 - Output - Data bit 4
D3 - Output - Data bit 3
D2 - Output - Data bit 2
D1 - Output - Data bit 1
D0 - Output - Data bit 0 (LSB)
RESET - Input - RESET - Low to reset
PWDN - Input - Power Down - High to activate