text:
Can't use millis() instead of delay
I am making a home coming/leaving light for car. First I want that whenever I press the car key lock, a timer will start for 10 seconds. And if I press a button twice within 10 seconds, pin 13 will remain high for 10 seconds. If I don't press the button it returns to the void loop or condition may get false. I am working on it but I'm not getting the correct approach. I'm not able to use millis twice in this program.
int buttonPushCounter = 0;   // counter for the number of button presses
int buttonState = 0;         // current state of the button
int lastButtonState = 0;
unsigned long previousMillis = 0;
const long interval = 5000;

void setup() {
  Serial.begin(9600);
  pinMode(8, INPUT_PULLUP);
  pinMode(13, OUTPUT);
}

void loop() {
  unsigned long currentMillis = millis();
  buttonState = digitalRead(8);
  if (buttonState != lastButtonState) {
    if (buttonPushCounter <= 2) {
      if (buttonState == LOW) {
        buttonPushCounter++;
        Serial.println("on");
        Serial.print("number of button pushes: ");
        Serial.println(buttonPushCounter);
        if (buttonPushCounter % 3 == 0) {
          if (currentMillis - previousMillis > 10000) {
            digitalWrite(13, HIGH);
            previousMillis = currentMillis;
          } else {
            digitalWrite(13, LOW);
          }
        } else {
          digitalWrite(13, LOW);
        }
      } else {
        digitalWrite(13, LOW);
      }
    } else {
      buttonPushCounter = 0;
    }
    lastButtonState = buttonState;
  }
}

You are not using millis() at all in this program. You call it once at save the time stamp into a variable that you don't use afterwards.

I have edited the program as you said.

Please edit your program to get compileable code (Right now the braces don't match)
And please match your code to your description. You talk about 10s several times but in the code you use 5s

thanx for improving the code.but the led doesnt go off after 10 seconds.

Here is what you have asked for:

I am making home coming/leaving light for car. First i want that
  whenver i press car key lock a timer will start for 10 second.And if i
  press button twice within 10 second pin 13 will high remain for 10
  second and if i cant press the button it return to the void loop aor
  condition may get false. I am working on it but dont getting the
  correct approach . But i am not able to use millis twicely in this
  program.

So, I have refactored, and done my best to interpret your words, and the code that you wrote.
You will see that I broke down quite a bit the deep nesting of your code into separate methods.  I hope that you see that it makes it more readable and understandable.
I have replaced the "magic numbers" like 10000 with more readable code like tenSeconds.  And I hope the code does what you want now, but I'm not sure.  Hopefully the readability has improved enough that you can massage and reshape the code into what you want it to do, as well as shown you what direction to head when you don't understand your own code because it has grown (deeper, longer, more complicated, etc.) as most code does.
In the professional coding world, allowing code to remain like that is called "not paying down your design debt" and you (or your organization) will pay the consequences, with interest, just like a credit card.
Finally, note that my comments don't restate the code, but tries to add something (mine often tries to finish sentences involving readable code).  My comments also tend to be on the ends of lines to try to stay out of the way.
This code compiles, but has not been tested on an actual Arduino.  Please let me know if this meets your need, and please choose this as the answer if it does answer your question, and at least please vote up the answer if it doesn't quite answer you...   ...and give me a second chance, if possible.  Thanks.
// pins defined and named
int pin_button = 8;         // button Pin
int pin_LED = 13;           // LED Pin

int currentButtonState = 0;         // current state of the button
int lastButtonState = 0;

int buttonPushCounter = 0;   // counter for the number of button presses
unsigned long currentMillis = 0;
unsigned long previousMillis = 0;
const unsigned int tenSeconds = 10000; // 10,000 milliseconds

void setup()
{
    pinMode(pin_button, INPUT_PULLUP);
    pinMode(pin_LED, OUTPUT);
}

void loop()
{
    currentMillis = GetCurrentMillis();
    if (ButtonIsToggled() == 1)
    {
        CountButtonPushes();
    }
}

int ButtonIsToggled()
{
    int isToggled = 0;
    currentButtonState = digitalRead(pin_button);
    if (currentButtonState != lastButtonState)
    {
        lastButtonState = currentButtonState;
        isToggled = 1;
    }
    return isToggled;
}

void CountButtonPushes()
{
    int valueToWrite = LOW; // LED-OFF is default value unless overridden

    if (currentButtonState == LOW) // we just toggled from HIGH to LOW...
    {
        buttonPushCounter++; // We've successfully completed another button-press
        if (buttonPushCounter % 3 == 0) // if (buttonPushCounter==3) should be faster
        {                               // because compare is faster than division
            buttonPushCounter = 0;  // Reset
            valueToWrite = HIGH; // LED-ON
        }
    }

    if (valueToWrite == HIGH) // LED is ON
    {
        digitalWrite(pin_LED, HIGH); // valueToWrite
        while (currentMillis - previousMillis < tenSeconds)
        {
            // do nothing -- wait while LED is on
            // busy wait. Consider sleeping instead.
            currentMillis = GetCurrentMillis();
        }
        previousMillis = currentMillis;
        digitalWrite(pin_LED, LOW);
    }
}

unsigned long GetCurrentMillis()
{
    return millis();
}


text:
Arduino works indefinitely without PC contact
I'm studying H-Bridge for DC motors. I have a 9V battery, DC motor (9v), Arduino Nano and L293D. I'm following Jeremy Bloom's book about Arduino. Well, the system works perfectly with a PC connected. When I turn off the PC and connect the battery only, it doesn't work at all. The system should work only with a 9V battery.
const uint8_t MC1 = 8;
const uint8_t MC2 = 7;
const uint8_t POT = 0;

uint16_t velocity = 0;
uint16_t PWM = 0;

void forward(uint16_t);
void reverse(uint16_t);
void brake();

void setup(){
  Serial.begin(9600);
  pinMode(EN, OUTPUT);
  pinMode(MC1, OUTPUT);
  pinMode(MC2, OUTPUT);
  brake();
}

void loop(){
  Serial.println(PWM);
  PWM = analogRead(POT);
    if (PWM > 562){
    velocity = map(PWM, 563, 1023, 0, 255);
    forward(velocity);
  }
  if (PWM < 462){
    velocity = map(PWM, 461, 0, 0, 255);
    reverse(velocity);
  }
}

void forward(uint16_t speedValue){
  digitalWrite(EN, LOW);
  digitalWrite(MC1, HIGH);
  digitalWrite(MC2, LOW);
  analogWrite(EN, speedValue);
}

void reverse(uint16_t speedValue){
  digitalWrite(EN, LOW);
  digitalWrite(MC1, LOW);
  digitalWrite(MC2, HIGH);
  analogWrite(EN, speedValue);
}

void brake(){
  digitalWrite(EN, LOW);
  digitalWrite(MC1, LOW);
  digitalWrite(MC2, LOW);
  digitalWrite(EN, HIGH);
}```

The A0 pin is used to rotate the sensor (PWM).

[![The circuit][1]][1]

  [1]: https://i.sstatic.net/GliSw.png

Did you use this type of 9 Volt battery? These types of battery do not have enough current capacity to run most type of motors. Consider using batteries with more current capacity. Likely the type used in older flashlights would work better.

Yes, i did. Which one should I use?

Well, I connected 7.4V 1500mAh Li-ion battery and... it's working. Could you explain why??

Well, I connected 7.4V 1500mAh Li-ion battery and... it's working. Could you explain why??

The PP3 batteries (rectangular 9v battery with snap-on terminals) can supply only a very limited amount of current; barely enough to run an Arduino at all, and none left over to run a motor or other higher current devices.
The best application for PP3s is in low-current, standby devices like smoke detectors, which need very little current under normal circumstances (no smoke) but can draw enough current to make a lot of noise for long enough to wake you up and alert you to the danger, when they detect smoke.
For your application you need a larger capacity battery that can supply more current. Carbon, Alkaline, and nickel chemistries could all work, provided the battery is large enough to supply the current you need; the PP3's form factor is its limitation. Li-ion's big advantage over the other chemistries is, of course, it's rechargeability, and with less degradation than Nickel-based rechargeables.

source: Stack Exchange

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

sort: votes


text:
Make an Xbox 360 controller with an Arduino Uno
I was thinking of making a custom Xbox 360 controller (racing wheel) with the Arduino Uno plugged into the Xbox. How would I emulate the buttons/triggers on the original controller with the Arduino? Is there a library that can help me do this?

you may or may not be able to do it with your Uno .... it depends on the kind of the USB to serial converter the board uses ..... what kind of a chip do you see near the USB connector?

I googled a bit at this topic. It seems, that at least most (if not all) Xbox360 controller emulations/DIY builds cannot be used with the Xbox360 itself, but only with a PC. The reason is, that a Xbox controller incorporates an extra security chip, which performs some form of handshake, before the console really accepts the controller. Some sites stated, that some chinese producers cracked that chip, to produce knockoffs, but I couldn't find a hint to a published crack. It might exist,  you may have to google much. If you find something, this will most likely be no beginner project.

If you decide, that using it only with a PC is ok, you should look at Arduino boards, that have a configurable USB connection, so that the Arduino can behave as a HID device. This is also possible with the Uno, but not as good and only with reflashing the USB to serial controller.

Thanks for pointing me in the right direction. Would I be able to emulate it with something more powerful like a raspberry pi? I also searched some more and found some stuff about PID and VID, is this what you meant by the security key or is there more to it? P.S here is a tutorial I was referring: link. There was also this repo on the "falcon panel"

PID and VID are definitions for the USB connection. They are used to identifiy the type of a device, that is connected via USB. Seems, that it can be changed. But despite that it will still just advertise itself as HID device. If you google for Xbox360 controller emulation, you find many people, who talk about a real extra chip on the controllers pcb, which does some kind of secret handshake. Without a real crack for this, you won't be able to get any DIY controller working with the Xbox360. Microsoft uses the security chip to actively prevent others from doing this.

VID and PID are just numbers that are associated with a Vendor and Product. They don't define what it is, only who it is and what it's called.  What it does is defined by the device descriptor - a large block of data that defines protocols, endpoint types, block sizes, etc.

The GIMX open source project may help. The GIMX adapter plugs into the console and a computer running Windows or Linux (raspberry pi has experiemental support). A real xbox controller must be plugged into the computer so it can do the xbox authentication. Off the shelf or custom controllers plugged into the same computer can talk to the Xbox console.

Ohh... That looks interesting. This might work! Thanks for the suggestion. Will let you know if this works out.

Arduino Uno's do not have a native USB Connection. However, if you use an Arduino Leonardo or Pro Micro, you can use MHeironimus's Joystick library, However I am not sure if they are specifically compatible with the XBox.
https://github.com/MHeironimus/ArduinoJoystickLibrary

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


text:
Motion Tracking Using Arduino?
I'm trying to make a human following robot.Tried using ultrasonic sensors to follow a specific person by Having ultrasonic sensor with the person to send echo to the robot,But it didn't workout.
Any way to track a specific person and follow ?
Any sensors/algorithm to track fast moving object(a person but not specific)?

If you are clever with software you may be able to simplify your hardware requirements down to 1 IR ASK transmitter and 1 IR ASK IR receiver.
I mention IR ASK as the transmitter (simply a remote control with a button pushed down) and the receiver are COTS parts.
Consider your robot looking for an IR ASK signal by rotation until one is found.  Then consider your robot traveling in a serpentine path adjusting its average vector along the angle where the IR ASK transmitter is detected.
You might need to create an variable aperture the IR ASK receiver will look through.  This is because most IR ASK receivers have a built in AGC circuit which will abstract you from knowing how strong the signal is.
So, while searching, the aperture will be large allowing the IR ASK receiver a wide field of view.  But once locked on, the aperture should be reduced so that the robot will know in which direction the IR ASK signal is from.

You need the person to emit a signal and the robot to receive it, sounds simple, but it isn't.  What you are trying to do is position fix the transmitter, in the same way as an ATC locates a plane.
The robot will need at least two directional receivers positioned a certain distance apart (depends of frequency and accuracy) to allow the robot to triangulate the transmitter.  The more receivers the more complex the triangulation.  The frequency of the signal you transmit will affect the distance that the robot can be from the person, research Frequency spectrum and transmission distances.  The longer the distance the signal can travel the stronger the signal will be at close range.  You also have to counter reflections and side lobes which will give you inaccurate readings on the transmitter direction.
Once you have dealt with all of that all you need to do is scan for the strongest signal on your frequency, triangulate it and then head towards it.
Whatever sensor you use the theory is the pretty much the same.
Could you tag the person with a GPS receiver and WIFI/BT and get it to transmit its location.  The robot could then consult its GPS and calculate the delta and move accordingly.

considering tracking a person in a supermarket will it do work (Small Area)??

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


text:
Sending a text/notification with Arduino + ESP8266 Wifi shield
Is it possible to send a text message using an Arduino and the Sparkfun ESP8266 Wifi Shield using Temboo? I noticed that the ESP8266 might not be supported by Temboo and I was wondering if there is a workaround.
Thanks.

I work at Temboo.
While we don't officially support the ESP8266, we've found a couple of forum posts in which people have been able to get Temboo to work with the ESP8266. Here you go:
http://www.esp8266.com/viewtopic.php?p=24019
https://forum.arduino.cc/index.php?topic=337186.0
If that doesn't help, feel free to contact Temboo Support and we'll do our best to help figure out what's going wrong for you.
The key piece of info you need to be aware of is that you need to modify following Temboo library files:
\Arduino\libraries\Temboo\src\Temboo.cpp

\Arduino\libraries\Temboo\src\utility\
--ChoreoInputFormatter
--ChoreoOutputFormatter
--ChoreoPresetFormatter
--TembooSession
--tmbhmac
--tmbmd5

You need to modify all occurrences of "avr/pgmspace.h" in these files, changing it to "pgmspace.h".

Could you add a folder called avr and a file called pgmspace.h with #include "..\pgmspace.h" in?  If you could that would save re making the change if you updated the Tembo library.

Thanks for the suggestion, @Matt. I'll certainly pass it on to our dev team.

I meant for the original poster, but if it works :)

Yes, apparently you can.
I did a quick search on Google and found a GitHub library for the ESP8266 https://github.com/sabas1080/TembooForESP8266 and a post on the Arduino Forum https://forum.arduino.cc/index.php?topic=337186.0 that says you can download a skeleton program and hack that.

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


text:
Use AGPS functionality with Arduino and GPS module
Recently, we developed the UTRAQ L100 GNSS Module base board for testing all the capabilities of the GPS receiver.
https://www.elementzonline.com/blog/utraq-gps-l100-module-based-on-irnss-supported-by-gagan-navic
But we couldn't find a way to use the AGPS functionality. Is there any AGPS server available that can be used to download the satellite ephemeris data and feed that to the GPS module?
I got a reference that uses Skytraq AGPS, but not sure if the same is applicable for all receivers with AGPS functionality.
https://github.com/r0ro/skytraq
The above reference uses python code, but hopefully, it can be ported to an Arduino library if the functionality actually works well.


text:
Powering NodeMCU with battery and LDO; what if battery is empty?
I want to battery-power my NodeMCU. It will be mostly deep sleeping and waking up every 1-2 minutes.
I've seen the best way to power it with the least wasting of power is through a lithium battery.
So I've bought a 18650 rechargable battery and a MCP1700 LDO which will give me a constant 3.3 V, that will connect straight to the 3.3 V pin and bypass the NodeMCU's regulators, as I understand from here.
My question is: If all of the previous is correct,

What will happen when the 18650 battery power falls below the 3.5 V (3.3 V + 0.2 V from MCP1700 dropout)?
Will it stop automatically giving power at all?
Will it provide less than 3.3 V and will it harm the NodeMCU?

google nodemcu brownout

does the cell have an integrated protection board? if so, then it will just cut-off.

If you battery come with flat head with exact 6.5cm long, it likely is an unprotected type without the built-in over-votage, under-voltage shut down circuit. You will need to get your own protection circuit. Even with the protection circuit, it is likely that cut-off will be around 3v instead of 3.5v. ESP8266 operates at 3.0v to 3.6v, so when your regulator input fall below 3.3v, it won't cut off with or without protection circuit, your regulator will not function properly as it is supposed to be.

If your regulator input voltage is lower than 3.3v, it will not shutdown, it simply unregulated. ESP8266 works between 3.0 to 3.6v, as it draw quite some current at power-up of the WiFi (170mA), it could cause the voltage drop to 3.0v, which will crash the ESP8266. To prevent this happen, make sure your MCP1700 output has a bigger capacitor than recommended 1uF on the datasheet.

One thing you could do, is have the MCU read the input voltage, and automatically run a script to shut down when the voltage gets lower than a certain point. You might be able to do it with the pins on the MCU directly, but you will probably need to use an ADC.

As with any electronics, once you get outside of normal operating parameters, behaviour becomes undefined. It's up to you to avoid that.
The smartest thing to do is to employ a battery protection circuit or some means to shut down the system (or prevent it from waking up from deep sleep) before the voltage drops too low. This will also prevent your battery from damage by overdischarging it.
The ESP's minimum operating voltage according to its datasheet is 3.0V. Below that, behaviour is undefined but you can expect unreliable operation, crashes or even permanent damage. If you're writing to Flash memory when below the minimum voltage, the Flash might become corrupted (including the program the ESP is running).

I totally agree..i don't want in any case let esp work under 3v..so..from your answer i understand that the ldo i suggest does NOT provide you this safety..
Could you suggest a circuit that turn will power of the whole system if ldo output is less than 3V?

As far as I can see the MCP1700 does not have an undervoltage protection so I would expect the output voltage to gradually drop when the input falls below the LDO threshold. There are numerous Battery Protection boards available that could provide you with an automatic shutdown safety. You could also use the ADC of the ESP8266 to let it monitor its own supply voltage and take appropriate action.

i guess something based to TP4056 that will shutdown at a specific voltage?
about the ADC, so i connect LDO ground to esp ground, then batteries positive (LDO in) to a esp pin, and in this way "analogRead" my battery voltage?

TP4056 is a charging IC, it is not a voltage regulator. The TP4056 itself does not provide the protection circuitry, some of the TP4056 board has extra circuitry that come with a DW01A chip and 8205 dual-MOSFET to provide the battery over-charge (4.2v), over-discharge (below 3v) protection. You still need the MCP1700 regulator to get 3.3v.


text:
With TIMER1 in CTC mode can't get above ~200khz in arduino UNO runnning @ 16MHZ with no prescaller?
I got the following code, and based on the datasheet the Freq should be clk / 2 * Prescaller * (1 + OCR1A) making it that if I set the OCR1A to 0, I should get something close to 8Mhz, but the maximum I can get is ~200kHZ.  Can anyone help me understand why?
In FAST PWM MODE I can reach those speeds, just wanted to know why i can't in CTC MODE.
    void setup() {

        DDRB |= (1 << PINB1) ;
        TCCR1A = 0;
        TCCR1B = 0;
        OCR1A = 0;
        TCCR1B |= (1<<CS10) | (1<<WGM12);

        TIMSK1 |= (1<<OCIE1A);
        sei();
    }

    void loop() {

    }

    ISR (TIMER1_COMPA_vect){
        PORTB ^= 1 << PINB1;
    }

You cannot dispatch an ISR and return fast enough to get anywhere near 8MHz in CTC. But you also cannot do this for Fast PWM mode either. So, I don't know what to make of your question. Did you mean using the actual PWM functionality and just put the ISR in your code as a mistake? Alternately if you were able to get 8 MHz doing this same thing with an ISR and Fast PWM mode, I'm curious to see how.

Hello, thanks for your reply.
No, i can get the 8mhz using fast pwm without interrupts (yes to your question on the using the pwm functionality), just using the ICR and OCR1A registers and set them to 0.
I imagined it was something related to the time being consumed by the interrupt calls, but couldn,'t figure out the timings that jumping to the ISR takes.

I even went to the Microchip IDE and emulated the atmega, but it doesn't implement the ISR very well (either that or i don't know how to), cos i could only trigger the the ISR call when "playing" the debug and couldn't trigger it using the step by step instruction but i manage to get that for a 8MHZ clock the isr was triggered every 5us or something like that i think it was 38 instruction cycles, or close to that, but i coulnd't figure out where did those instructions came from.

I think i got thrown off by this on the atmega datasheet : The waveform generated will have a maximum frequency
of fOC1A = fclk_I/O/2 when OCR1A is set to zero (0x0000). The waveform frequency is
defined by the following equation:
So i was expecting a ~8mhz pulse.

I disassembled your program. Below is the code for the ISR. Next to each
instruction, I wrote the number of CPU cycles it takes, as a comment:
; Prologue: save some registers to the stack.
push r1         ; 2
push r0         ; 2
in   r0, 0x3f   ; 1
push r0         ; 2
clr  r1         ; 1
push r24        ; 2
push r25        ; 2

; ISR body: PORTB ^= 0x02;
in   r24, 0x05  ; 1
ldi  r25, 0x02  ; 1
eor  r24, r25   ; 1
out  0x05, r24  ; 1

; Epilogue: restore registers and return.
pop  r25        ; 2
pop  r24        ; 2
pop  r0         ; 2
out  0x3f, r0   ; 1
pop  r0         ; 2
pop  r1         ; 2
reti            ; 4

I count a total of 31 CPU cycles, most of them spent in the
prologue and epilogue. Then, there is some overhead:

The CPU always executes at least one instruction of the main program
between two interrupts. Given that the main program is in a tight loop
containing only two double-cycle instructions, that will take two CPU
cycles.

The CPU takes four cycles to enter interrupt mode: prevent nested
interrupts, save the program counter and load the address of the
interrupt vector.

The interrupt vector is a jmp instruction that jumps to the ISR.
This takes three cycles.

The minimal interrupt period is then given by this sum:
 2  one loop instruction
 4  enter interrupt mode
 3  jump to ISR
31  execute ISR
────────────────────────
40  total cycles

This takes 2.5 µs, giving an interrupt frequency of 400 kHz.
Given that you need two interrupts for a full cycle of the output
signal, the maximum you can see on the output is then 200 kHz.
You can save 10 CPU cycles by toggling the pin with:
    PINB |= 1 << PINB1;

This line compiles to a single double-cycle sbi machine instruction.
As this instruction doesn't access any CPU registers, you don't need to
save and restore r24 and r25. Actually, you don't need to save and
restore any register, so you could just remove the prologue, and replace
the epilogue by a single reti instruction:
ISR (TIMER1_COMPA_vect, ISR_NAKED) {
    PINB |= 1 << PINB1;
    asm("reti");  // return from interrupt
}

This gives an ISR that executes in six cycles, and the total interrupt
period can then be as small as 15 cycles. Beware though, that you
should not write a naked ISR unless you are absolutely sure that the
code within it will not clobber any CPU register, nor the status
register.

Clarification: On the face of it, the instruction
PINB |= 1 << PINB1;

seems to mean: “Load PINB, do a bitwise OR with 0x02, then write the
result back to PINB”. This is, however, not how the compiler
interprets it. Instead, it takes it to mean “set bit 1 of register
PINB to one”. This happens to be a single machine instruction, as
PINB is a bit-addressable I/O registers.
Yes, the avr-gcc compiler may be a bit peculiar in this respect.

First of all, thanks so much for that detailed explanation. i did tried to include that ISR_NAKED option, and it doubled the frequency.
One thing i didn't understand is that you said you can toggle the pin with the |= ? i tried it and it stays always on, i can only toggle with the ^= operator, am i doing anything wrong?

PINB |= 1 << PINB1; can just be PINB = 1 << PINB1;

But that doesn't toggle the pin, do i need to set any register?

@NunoSantos the behaviour of writing to  1-bit to PINx causes that pin to toggle in PORTx. I know it looks weird, but that's how it works on these chips.

Wait, not sure if i totally understand you, bare with me, i'm a noob...
So, i had the pin toggling, with the XOR operator., but when i change to the OR ou even just setting the pin with the Equal sign, i get no tggling on that pin, after reading your comment i went to the datasheet because i remember reading that there was one bit in a register that did just that, so i updated my code with the line TCCR1A |= (1<<COM1A0); and NOW it toggles if i set the PIN to HIGH inside the interrupt, not sure if it was this you were talking about.

Cos in my posted version of the code, when i switched the XOR for the OR or just pin assignment, i get no toggling on that pin.

@timemage: PINB = 1 << PINB1; is no faster than PINB |= 1 << PINB1;. Also, setting the pin with = clobbers a CPU register that you would have to save and restore. You then cannot do without the prologue and epilogue.

@NunoSantos: You should not replace a XOR by an OR: you should replace PORTB ^= 1 << PINB1; by PINB |= 1 << PINB1;. Notice that we are acting on a different I/O register: PINB instead of PORTB.

@EdgarBonet regarding the faster part, that wasn't the point of it. Regarding the second part: odd.

Ohhhh i see now, you are setting the PINB not the PORTB, i just tried and works without setting the COM1A0 bit, why is that? why setting the PIN directly toggles a pin off?
And once again, thanks for you time, and sorry for this noob questions

with your code i get 517kHZ, thats more than double what i had before.

@NunoSantos: The AVR I/O ports have this toggle functionality built-in. It has been piggy-backed on the PIN register, for which a write operation would otherwise be meaningless. Likely a way to save on I/O address space. See the ATmega datasheet.

@EdgarBonet i was reading the datasheet, and the PINx register is marked as a R only register, while the PORTx and DDRx and R/W, but this is good to know, altough even if you write to them the change won't stay, it's nice to have that functionality. Didn't know that! Thanks so much.


text:
PubSubClient hanging on ESP32C3
I may have done some things incorrectly here, but this I what I have for publishing image that I read from serial camera to the MQTT broker:
void capturePicture() {
  if (!cam.takePicture())
    client.publish("info", "Failed to snap!");
  else
    client.publish("info", "Picture taken!");

  char length[21];
  uint32_t jpglen = cam.frameLength();

  sprintf(length, "buffer length: %d", jpglen);
  client.publish("info", length);

  byte wCount = 0;  // For counting # of writes
  client.publish("info", "transfer about to begin");
  client.beginPublish("picture", jpglen, false);
  client.publish("info", "after beginPublish");

  while (jpglen > 0) {
    uint8_t* buffer;
    uint8_t bytesToRead = min((uint32_t)16, jpglen);  // change 32 to 64 for a speedup but may not work with all setups!
    buffer = cam.readPicture(bytesToRead);

    client.write(buffer, bytesToRead);

    jpglen -= bytesToRead;
  }

  client.endPublish();
  client.publish("info", "transfer should have ended;");
}

I know the board is working, I am connected to the broker and I can receive messages.
In the loop I am reading few sensors and pushing the string into the topic
void loop() {
  delay(1000);

  if (count == 5) capturePicture();

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

  int multi = analogRead(A2);
  int odor = analogRead(A1);
  int voc = analogRead(A0);

  char name[21];
  sprintf(name, "%d;%d;%d", multi, odor, voc);

  bool pubScss = client.publish("measurement", name);

  count++;
  client.loop();
}

and all that works fine.
what happens when capturePicture() gets executed is this:
Picture taken!
buffer length: 49048
transfer about to begin

--that's what I see on the topic's subscriber side, then it freezes for about 10secs and then it continues with sending messages from the loop.
So it seems like it never gets past client.beginPublish("picture", jpglen, false); call.
I'm setting PubSubClient's buffer size to client.setBufferSize(10235);
What can be happening here? Something I can further test??

The short form of the below is something like: "After calling .beginPublish(), call .endPublish() before making a call to either .publish() or .beginPublish().

We don't have your actual code. And that makes things difficult.
However, this is a source of problems in what you have shown:
  client.beginPublish("picture", jpglen, false);
  client.publish("info", "after beginPublish");
  ...
  client.endPublish();

It kind of looks like you may intended the second publish to help you debug the initial problem. But again, we don't have your code. I don't know if this (or something just like it) is in your original. In any case, it's not doing you any good as a debug aid.

The .beginPublish()/[.write()-type stuff]/.endPublish() constructs a message in the MQTT protocol as you make these calls.
By inserting .publish() call between them you are corrupting the communication. In short, you're embedding an MQTT message part way inside of another MQTT message.
Something a bit like saying
HowHello. are you today?

instead of
Hello. How are you today?

This is confusing something, probably the server. Perhaps also the library itself and any client that receives whatever the server ends up passing along.

I tested with a few variations on this code:
//#define CAUSE_TROUBLE

void one_shot_message() {
  client.publish(MQTT_TOPIC, "[hi]");
}

void do_test() {
  static const char part1[] = "<Hello";
  static const char part2[] = " World>";
  static const char both_parts_length = // just being very explicit
      (sizeof part1 - 1) // part1 sans null terminator
    + (sizeof part2 - 1);// part2 sans null terminator
                       // the .publish accepting strings doesn't null terminate, so we aren't.

#ifndef CAUSE_TROUBLE
  one_shot_message(); // okay before beginPublish or after endPublish
#endif

  client.beginPublish(MQTT_TOPIC, both_parts_length, false);
#ifdef CAUSE_TROUBLE
  one_shot_message(); // not okay between beginPublish/endPublish
#endif
  client.print(part1);
  // tested with one_shot_message() called here (not-okay location) as well
  client.print(part2);
  client.endPublish();
}

What happens in the case of #define CAUSE_TROUBLE (at the least with server I'm using and the client I've written on a PC) is that a single corrupt-looking message comes through and then the ESP32 client reconnects to the server. Probably the server is closing the connection. It does this on a cycle of about 6 seconds. The corrupt message has the correct topic, which makes some sense because the topic is written as part of the .beginPublish() before there's an opportunity to corrupt the message. This may not be exactly what you're seeing, but I don't have good cause to think I should be seeing exactly what you're seeing; not the same exact code, client, server. It is similar anyway.

So, you can have client.publish("info", "before beginPublish");
or a client.publish("info", "after endPublish"); at those locations, but not between the begin and end calls. If you wanted to try doing something like that, you probably could probably do so by creating a second PubSubClient so that you could fire off these smaller messages in a separate protocol stream while in the middle of constructing/sending a larger message on the main stream.  However the messages may not arrive in order, either because the of how the library works or because of timing in the network. So if you want to do that you may also want to send a counter value with each message so you can reconstruct the timeline in the sending code.
An aside regarding sprintf vs snprintf:
  char name[21];
  snprintf(name, sizeof name, "%d;%d;%d", multi, odor, voc);

sprintf() is something that exists to support very old code or very old compilers.  There's otherwise no use case involving sprintf() that would not be better using snprintf()


text:
Strange binary number representation
I have a very simple sketch, something like this:
int aFour = 4;
softwareSerial.print(4,BIN);
softwareSerial.print(aFour,BIN);

Which gives the following output:
1001
0011

Why don't they print both as 0100?
EDIT: the output was in one line : 10010011, I falsely asumed the output should be split into twice 4 bits.

Works for me. How it's even separated? Maybe it's 100 100 11 or so because you did just print not println ...

I also got a 100 when I tried it. @KIIV did raised a good point about println.

print never prints leading zeroes (how many should it print anyway?).
print doesn't start a new line - you need println for that

So you get your 4 in binary printed twice followed by something else (not sure what - maybe something else in your program that you're not showing us?): 10010011
That's 100 100 11 when split up.

I indeed falsely assumed the output to be split 4 bits each. println clarified the issue. The lagging 11 originated from some other print statement not displayed in my question above. Thanks!


text:
Arduino - read multiline serial input
I'm trying to get data from a heat counter via the serial, the format of the response is:
t1=ХХХ.ХХ   t2=ХХХ.ХХ   t3=ХХХ.ХХ   t4=ХХХ.ХХ
P1=ХХ.ХХ    P2=ХХ.ХХ
VolSpd1=ХХ.ХХХ  VolSpd2=ХХ.ХХХ
MassSpd1=ХХ.ХХХ MassSpd2=ХХ.ХХХ
HeatSpd1=Х.ХХХ  HeatSpd2=Х.ХХХ
SumVolume1=Х.ХХХХХХХ    SumVolume2=Х.ХХХХХХХ
SumMass1=Х.ХХХХХХХ  SumMass2=Х.ХХХХХХХ
SumHeat1=Х.ХХХХХХХ  SumHeat2=Х.ХХХХХХХ
PowTime=Х.ХХХХХХХ   PowOffTime=Х.ХХХХХХХ
MeasTime1=Х.ХХХХХХХ MeasTime2=Х.ХХХХХХХ
UnMeasTime1=Х.ХХХХХХХ   UnMeasTime2=Х.ХХХХХХХ

I managed to get the data and parce it on arduino but only from the first line. I do not know how to get all other data.

Since the format is just = , I'd parse it this way, instead of relying on newlines.
Just treat them as whitespace. So buffer all data till an = sign is found, store the buffer as the variable name, then read until you get something other than a digit or decimal point. Then store this as the value. Then do something with the value based on the variable name. Then read and ignore all following whitespace (spaces, tabs, newlines, carriage-returns). And start back from the top.
That way the parse will never get out of whack when some data get missing or something else goes wrong in the serial stream.

Could you support me with the code?

First give it a try yourself. Come back if you have any questions.


text:
VP230 CAN Bus Transceiver
How does one read can packets from a VP230 Can Bus transceiver? I also have a MCP2515 which I've gotten to work, but the VP230 is a lot smaller.
I haven't been able to find any information about actually implementing the VP230, any help would be great.

Welcome. You are talking two compatible CAN parts but they have different functions. The VP230 is the CAN bus bidirectional interface. This converts the signals on the CAN bus to logic signals your CAN controller can use. The MPC2515 is a CAN controller chip that talks to your microprocessor and the bus transceiver. The MCP2515 has only logic signals and is not compatible with the CAN bus. Together they make a good CAN bus interface. Both parts are 3V3 compatible.

So may I ask, when I connect my VP230 to my arduino, and read serial from it, what data am I reading

I am assuming it is connected to the MCP2515 and that is converting the CAN data. However I do not know. It depends on what you have it hooked up to.
Connecting the VP230 to serial will probably just give you garbage, the format it will receive is not compatible with async serial.  You need the  MCP2515 or similar part to convert the data. CAN has a lot of control bits in its transmission that will not make sense unless you use a CAN controller chip.  You can have the Arduino convert that to serial if you want. Look at the send.ino and receive.ino in the Cory Fowler library.


text:
Separate ATmega 2560 - turn on a single LED - troubleshooting
I have got my own PCB with "some stuff" on it and first I want to make it run a simple "turn on LED".
My setup:

Atmega 2560
LED connected to PE4 (D2 in Arduino language) => PE4 - LED - 1K resistor - 5V
ceramic resonator (CSTCE16M0V53-R0 16MHZ) connected to XTAL1 + XTAL2 with 1MOhm resistor in between
all VINs are pulled to GND with capacitors

Upload is working through ICSP (MISO, MOSI, SCK, RESET, 5V, GND) with an USBasp
Here is my Arduino sketch, which I upload through the Arduino software:
void setup() {
  pinMode(2, OUTPUT);
}

void loop() {
  digitalWrite(2, LOW);
}

I checked the fuses on the Atmega as well:
avrdude: safemode: lfuse reads as FF
avrdude: safemode: hfuse reads as D8
avrdude: safemode: efuse reads as FD
avrdude: safemode: Fuses OK (H:FD, E:D8, L:FF)

avrdude uploads successfully: (output truncated!)
avrdude: auto set sck period (because given equals null)
avrdude: AVR device initialized and ready to accept instructions
Reading | ################################################## | 100% 0.01s
avrdude: Device signature = 0x1e9801
avrdude: NOTE: "flash" memory has been specified, an erase cycle will be performed
         To disable this feature, specify the -D option.
avrdude: erasing chip
avrdude: auto set sck period (because given equals null)
avrdude: writing flash (1518 bytes):
Writing | ################################################## | 100% 5.47s
avrdude: 1518 bytes of flash written
avrdude: reading on-chip flash data:
Reading | ################################################## | 100% 3.45s
avrdude: verifying ...
avrdude: 1518 bytes of flash verified

avrdude done.  Thank you.

Problem: the LED doesn't work. It is OFF all the time.
Any ideas why it is not working?

You have forgotten to mention what the problem even is.

You're right. I edited my post. The LED isnt blinking.

Have you tested the voltage at the pin?

When you say it doesn't blink, can you clarify: Is it on all the time, or off all the time?

it is off all the time. @NickGammon
// which pin do you mean

At the pin that's supposed to be blinking.

Try pin D52 (the SCK pin) since we know that works or you wouldn't have been able to upload the sketch in the first place.

Everything on the PCB is already hard wired and I cannot change. I can try to pull a temporary cable from D52 to the LED. I will give it a try // I will also test the LED itself (just apply 5V) and I will measure the voltage when I remove blinking and just turn the LED on. Will come back later!

Well, you should have access to the SCK pin, because you use that to program the thing. It's what you plug the ICSP cable into.

I updated the original question: I need to pull the output pin to LOW to make the LED work ( PE4 - LED - 1K resistor - 5V). When I put a cable between PE4 and GND the LED works. I have no LED attached to SCK but I can attach one to the ICSP header where I have connection to the SCK pin. Good idea! @NickGammon

You haven't mentioned any capacitors - any of the required decoupling capacitors on the power pins, the critical capacitors on the crystal, etc.  Also you haven't mentioned what your reset circuitry is like - are you pulling the RESET pin HIGH through a resistor?  Show your full circuit

I mentioned the capacitors of the power pins in my original question. They are all conected to GND with a 100nF cap. The crystal has got internal caps and RESET is pulled to HIGH with a 10K resistor. @Majenko

@jblaze That's not a crystal, that's a ceramic resonator - a very different beast.

@Majenko OK sorry, you are right. This comes straight from the Arduino2560 reference design.

@Majenko I added the relevant circuits to the original question

@jblaze Do you have an oscilloscope?  Can you see if the resonator is oscillating at 16MHz?  (Tip: set the probe to 10x)

@Majenko sorry I don't have an oscilloscope

@jblaze Then you really should see about acquiring one - even a dirt cheap ancient analog one from eBay that you can get for next to nothing.  They are an essential piece of equipment for circuit diagnostics.

@Majenko Thanks for the hint. When there is a problem with the crystal/ceramic resonator, would I have been able to program the Atmega?

@jblaze Quite probably yes - I can't remember the details on the Atmel chips, but either it uses the incoming SCK as the system clock, or it switches to the internal 1MHz RC clock, I forget which - it allows you to set the fuses regardless of what the rest of the circuit is doing.

I need to pull the output pin to LOW to make the LED work - I see. But it doesn't blink? It won't with your altered sketch.

@NickGammon I only want it to turn on for the first shot.

I'm losing track of your problem. The way you wired it, as far as I can tell, you expect it to turn on if you digitalWrite LOW to it. You initially said it didn't blink, and then you said I need to pull the output pin to LOW to make the LED work - so working as expected. What are you expecting exactly?

You are saying that the LED lights if you write LOW to it.

I need to pull the output pin to LOW to make the LED work

That's exactly what you expect.

Since the other end of the LED is wired to +5 V, then you need to drive the pin low to have a voltage difference over the LED, and for it to light.

I double checked the Atmega and it is a ATmega2560V, which is rated for 8Mhz. Any chance to fix this with the existing PCB? Change the Fuses to use the internal clock?

Yes, I suggest you do that.
Look at Engbedded Atmel AVR® Fuse Calculator to see what to set them to. I suggest the internal 8 MHz oscillator.

Yes, I have to pull it LOW but nothing happens.

Well it shouldn't take long to change the sketch to refer to pin 52 (SCK), upload that, jumper your LED to the SCK pin, and test.

Unfortunatly this doesn't work :-(

Please measure the pin with a multimeter. Upload your earlier "blink" sketch. See whether or not the pin changes voltage.

The pin set to LOW and measured against GND, the resistance is infinite. When I set the pin to high the voltage swings between 5-8mV.

Can you post a photo of you measuring that pin? I can't believe that you can upload new code, but the SCK pin is incapable of behaving like a normal pin.

Here it is: measure1 and measure2 - I disconnected SCK and 5V and measured between both pins

Normally voltages are measured with reference to GND. So what I expect you to do is run the sketch, and while the board is powered measure between the SCK pin and the GND plane.

OK, let me describe in detail: first I set SCK to HIGH and measured against GND: 5-8mV. Afterwards set SCK to LOW and measured against 5V: 0V.

I double checked the Atmega and it is a ATmega2560V, which is rated for 8Mhz. Any chance to fix this with the existing PCB? Change the Fuses to use the internal clock?

See amended answer.

OK thanks. Are these appropriate fuses to go for? "-U lfuse:w:0xc2:m -U hfuse:w:0x99:m -U efuse:w:0xff:m"

it is working!! Thanks to all participants!


text:
Sending data through LoRa with ESP32-E
I have an Esp32-E from Firebeetle and LoRa from SBComponents. On both of these devices there are RX and TX pins. I believe that LoRa pins are just an extension of pins found on the Firebeetle.
My problem is that I don't know how to direct data into these pins for theLoRa module to send them. I'm using Arduino IDE for coding.
Thanks in advance for any and all help.

I believe it's one of those UART modules, with an MCU between the LoRa chip and the main MCU. You're going to need 2 things: A UART connection Rx-->Tx, Tx-->Rx, and the AT firmware or similar commands to send and receive data. You'd have been better off buying the Firebeetle LoRa extension.

You can try this connection:
LoRa MISO → ESP32 MISO (usually GPIO 19 on the ESP32)
LoRa MOSI → ESP32 MOSI (usually GPIO 23 on the ESP32)
LoRa SCK → ESP32 SCK (usually GPIO 18 on the ESP32)
LoRa CS → ESP32 GPIO5 (you can select any GPIO)
LoRa RST → ESP32 GPIO14 (or any GPIO)
LoRa DIO0 → ESP32 GPIO26 (or any GPIO)
Then try this code:
#include <SPI.h>
#include <LoRa.h>

void setup() {
  // Start Serial Monitor
  Serial.begin(9600);

  // Initialize LoRa module
  LoRa.setPins(5, 14, 26);  // CS, RST, DIO0 pins
  if (!LoRa.begin(915E6)) { // 915 MHz frequency for LoRa
    Serial.println("Starting LoRa failed!");
    while (1);
  }
}

void loop() {
  Serial.println("Sending packet...");

  // Start packet
  LoRa.beginPacket();
  LoRa.print("Hello, LoRa!");
  LoRa.endPacket();

  delay(1000);
}


text:
Arduino Nano max current from 5v pin if using 5v 1A wall adapter
I read several answers, but those can be confusing, because it depends on how you provide power to the Arduino.
What if I use a wall adapter with 5 V / 1 A and connect it directly to the Arduino Nano USB type-c port? How much current will that 5 V pin support then?
For instance, can I power a 1 A lamp from a 5 V pin and ground pin?
If no, what is a preferable way to do this if I still want to use a USB port?

wouldn't you expect the arduino to use some of the available current?

If you've got the wall adapter plugged into the USB port, then why not take power off of that instead and not have to worry about it.  Tap into the 5V in that wire.

Instead of powering the lamp from the Arduino's 5V pin, use a separate 5V power supply that can provide enough current for the lamp (e.g., a 5V/2A supply).

After working in digital electronic, analog electronics can catch many people off guard. A power supply rated up to 1 amp may not work well close to its rated limit. The voltage may drop unexpectedly.
Also, according to this schematic, on the Arduino Nano, between the USB voltage net (VUSB) and the 5 volt Arduino Nano net (+5V), there is a fuse (MSMF050) that operates in the 0.5Amp range and should trip at about 1.0Amps. Pulling the trip current may trigger this fuse.
Some people design with much wider margins. For example, if a device or part requires 1A to operate some people use a power supply who's limit is double or 2A.
Note, there is the fuse in the Arduino Nano that should trip at about 1.0A so using a larger power supply would not work here. Consider supplying power to the external device or part directly from a capable power supply.


text:
Is it possible to run a monochrome LCD without driver circuit with an Arduino Uno?
I have an old monochrome LCD panel that I removed from a calculator. The LCD panel has no standard input pins, because it's directly connected to a driver on which the calculator software runs.
Is it possible to run the LCD without the calculator software? All pins of the LCD would be available (marked in blue). The pins marked in red were connected to the keyboard of the calculator.

Depending on what it is you want to do with it; you could connect the Arduino to the keypad pins, and have the Arduino "type" the number you want to show. Though it's a bit more tricky than that, since the keypad is a matrix, so you'd have to time the fake button presses, so it's in sync with the calculator scanning the button matrix.

google lcd driver waveforms to get an idea of the kinds of signals you would have to generate .... here is one example https://aardvarklabs.files.wordpress.com/2013/04/waveforms.png ..... the problem with LCDs is that you cannot have a net voltage across a display element ... all the voltages placed across an element over a period of time must add up to zero ... the duration of positive voltages and the duration of negative voltages have to be equal, otherwise the display element will become damaged

Normally such LCDs are custom designed, mass produced displays especially for this calculator product. Thus it is very unlikely to find a datasheet or even a meaningful part number for it.
Most likely the pins on the LCD are directly connected to the corresponding fields on the LCD. In an LCD you have liquid crystals between two electrodes, which change their orientation, when a voltage is applied to the electrodes, which changes the light absorption of the layer. You need to apply the correct voltage to a pair of pins to activate their field. Most likely all of the fields or a few groups of them have a common electrode (which would be 1 pin). Without any documentation you are bound to experiment with the display, until you have found the correct voltages and pin arrangements. You might break the display in the process (for example through excess voltage).
I haven't done this myself, but googling gives an interesting result:

This project, where they hacked the LCD of a cheap calculator for a waveform generator (though the display seems to be way less complex than yours) They seem to use 1.5V as voltage, so this might be a good starting point.

Your display has many pins. Depending on the Arduino model, that you use, you will fast run out of pins to use. You can try arranging the pins into a matrix, which would mean multiplexing the fields (turning them on and off fast one after another). Or you can buy additional parts to extent your pin count, for example shift registers.

As jsotola wrote in the comments (and as several forum threads on web web state), you should not put a constant voltage onto the display, since this will damage it. (I guess the liquid crystals will degrade fast because of their polarity, which make the work in the first place). Instead you have to place an alternating voltage at the pins, which changes it's polarity. The  net voltage (The integrated voltage over time) must be zero. Thus you need to alternate the applied voltage. If you provide a span of 1.5V, you need to change between +0.75V and -0.75V.
As the display shouldn't need too much current and the voltage requirement is relative to the LCD ground, you might get way by setting the LCDs ground with a voltage divider to 2.5V and then operating around that. Though I'm not sure about that.
Otherwise you might need to actually change the polarity. This would also just need 1 extra digital output pin as the ground pin. One polarity would be the LCDs ground pin to Arduino's ground (outputting LOW at the digital pin) and the other pins to the needed positive voltage (HIGH divided down over a voltage divider or similar). The other polarity would be LCDs ground pin to the needed positive voltage (HIGH divided down over voltage divider) and the other pins to ground (outputting LOW).

As described above, hooking this bare LCD to the Arduino is not done fast and easy. You can try it, if you like to do it. But if you want to get your project (whatever it is) done fast, you should instead buy a LCD with integrated controller, which are mostly ready to use, and for which there are already libraries.

In theory, maybe yes, in practice it will be hard job.
Some things you need to find out:

Find the exact model of the LCD
Find its datasheet
I see an enormous amount of pins (especially the blue ones), so you need (a lot of) multiplexers or shift registers.
Speed of the Arduino, is it enough to drive this LCD?
You have to solder this to test.


text:
How to clear heap memory in ESP32?
I am using Free RTOS on ESP32 in my program. However at some point of time when I execute xTaskCreate() it returns -1 , the error being  could_not_allocate_required_memory. In my program, each time I pring getFreeHeap() it is reduced by 2,000 approximately and is never cleared or reset. When it is not sufficient or below 2,000 xTaskCreate returns -1.
After reading a lot of forums I could not find a way to clear the memory to create a task. Can anyone guide me with this?
code snippet
void createTsk(){
  SerialDebug.print("available Heap size: ");
  SerialDebug.println(ESP.getFreeHeap());

  BaseType_t xBy = xTaskCreate(taskPriorityOne, "TaskOne", 20240, NULL, 1, &thOne);
  SerialDebug.println("Return Val : ");
  SerialDebug.println(xBy);
}

void taskPriorityOne(void *paramter)
{
   SerialDebug.println("Prio 1 task Initiated");
   threadTask(priorityOneQue, "task1", thOne);
}

void threadTask(QueueHandle_t priorityQue, String taskName, TaskHandle_t th)
{
  xQueueReceive(priorityQue, &taskdataholder, portMAX_DELAY);
  ongoingProcess = taskdataholder;
  furtherExecutionHttp(taskdataholder, fnm, taskName, th);
}

void furtherExecutionHttp(DataHolder *taskdataholder, String fnm, String
taskName, TaskHandle_t th)
{
   String response = httpRequest(taskdataholder->protocol, taskdataholder-
   >host, taskdataholder->port, taskdataholder->url, taskdataholder->body,
   fnm);

  delay(10);

  free(taskdataholder);
  SerialDebug.println("Releasing memory..\n");

  vTaskDelete(th);
}

I don't know much about FreeRTOS, but memory on the heap can be cleared by deleting the dynamically created objects, that you don't need. Have you searched for a function in FreeRTOS to do this? In plain C/C++ it is just the delete operator.

@chrisl hi. thanks for the reply.
I am using arduino ide, hence i am not be able to do few custom modification. is there any more resolved way can you suggest ?

I'm not asking for "custom modifications". Code inside the Arduino IDE is just plain C/C++ with the Arduino framework (and the FreeRTOS framework in your case). You have some code (please show it in your question by editing it) and in this code you create objects dynamically. These objects must be deleted again. Someone must keep track over the objects, that are created, and free the memory, when they are not needed anymore. That can be you with your own code, or maybe the FreeRTOS framework (which I don't know enough to say, if it is capable of doing that).

@chrisl code added. please suggest.

xTaskCreate returns a pointer. You have to free it. When you're done with the task, you need to call xTaskDelete.

@PMF it is written in furtherExecutionHttp method at the end.

@Androing: Hmm.. True, that looks right. However, since thOne is a global variable, this only works if only one task is running at a time. If you start a new task while the old has not exited, the next call to xTaskDelete will delete the task that was most recently started, not the current one. Try xTaskDelete(null) to delete the current task.

is the http response about 2kb?

@dandavis 700-900 bytes

You probably don't want to "clear" the heap, assuming you mean either deallocating or zeroing all memory that you've allocated from the heap.
If you simply return all memory to the heap when you run out, your code may have pointers to that memory remaining when that memory gets allocated to another use, meaning some data will likely get over-written. Or, if you clear the heap (by zeroing it) you will be over-writing data already stored there, and possibly still be unable to allocate more memory if the allocator doesn't "know" that you meant to return it.
Instead, your code should free each memory allocation as soon as it is no longer useful, and make sure its pointer to that memory won't be used again. One way to protect re-use of dead pointers is 1) zero them when you deallocate the memory they point to; and 2) always test for a valid pointer (non-zero) before you try to use it.


text:
Has anyone heard of MCUDEV_TFT1.44 display? I can't figure out how to connect it to Arduino
I bought this TFT display on Aliexpress. It says "MCUDEV_TFT1.44" below the display.

I can't find online how to connect it to Arduino. The pins are as follows:
BLK RS RST CS SC DI GND VCC
On Aliexpress it says "Drive IC: ST7735" but I googled ST7735 displays and they have different pins. Does anyone have any idea?
Thanks!

BLK is probably Back Light (K)Cathode. RS is Register Select. RST is RESET. CS is Chip Select. SC is SCK. DI is MOSI.

@Majenko THANK YOU! I made it work :)

can you share you setting anh scheme connect

@DầuĐậuPhụ I posted it as an answer if you are still interested

If anyone else has the same display and iswondering how to make it work, here is how I connected and the script I used.
I couldn't find my display model so I just used this in Fritzing and added the pins names as a note.

#include <Adafruit_GFX.h>    // Core graphics library
#include <Adafruit_ST7735.h> // Hardware-specific library for ST7735
#include <SPI.h>

#define TFT_CS        10
#define TFT_RST        9 // Or set to -1 and connect to Arduino RESET pin
#define TFT_DC         8
#define TFT_MOSI 11  // Data out
#define TFT_SCLK 13  // Clock out

Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_MOSI, TFT_SCLK, TFT_RST);
float p = 3.1415926;

void setup(void) {
  Serial.begin(9600);
  Serial.print(F("Hello! ST77xx TFT Test"));

  // OR use this initializer (uncomment) if using a 1.44" TFT:
  tft.initR(INITR_144GREENTAB); // Init ST7735R chip, green tab
  Serial.println(F("Initialized"));

  uint16_t time = millis();
  tft.fillScreen(ST77XX_BLACK);
  time = millis() - time;

  Serial.println(time, DEC);
  delay(500);

  // large block of text
  tft.fillScreen(ST77XX_BLACK);
  testdrawtext("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur adipiscing ante sed nibh tincidunt feugiat. Maecenas enim massa, fringilla sed malesuada et, malesuada sit amet turpis. Sed porttitor neque ut ante pretium vitae malesuada nunc bibendum. Nullam aliquet ultrices massa eu hendrerit. Ut sed nisi lorem. In vestibulum purus a tortor imperdiet posuere. ", ST77XX_WHITE);
  delay(1000);

  // tft print function!
  tftPrintTest();
  delay(4000);

  // a single pixel
  tft.drawPixel(tft.width()/2, tft.height()/2, ST77XX_GREEN);
  delay(500);

  // line draw test
  testlines(ST77XX_YELLOW);
  delay(500);

  // optimized lines
  testfastlines(ST77XX_RED, ST77XX_BLUE);
  delay(500);

  testdrawrects(ST77XX_GREEN);
  delay(500);

  testfillrects(ST77XX_YELLOW, ST77XX_MAGENTA);
  delay(500);
  tft.fillScreen(ST77XX_BLACK);
  testfillcircles(10, ST77XX_BLUE);
  testdrawcircles(10, ST77XX_WHITE);
  delay(500);

  testroundrects();
  delay(500);

  testtriangles();
  delay(500);

  mediabuttons();
  delay(500);

  Serial.println("done");
  delay(1000);
}

void loop() {
  tft.invertDisplay(true);
  delay(500);
  tft.invertDisplay(false);
  delay(500);
}

void testlines(uint16_t color) {
  tft.fillScreen(ST77XX_BLACK);
  for (int16_t x=0; x < tft.width(); x+=6) {
    tft.drawLine(0, 0, x, tft.height()-1, color);
    delay(0);
  }
  for (int16_t y=0; y < tft.height(); y+=6) {
    tft.drawLine(0, 0, tft.width()-1, y, color);
    delay(0);
  }

  tft.fillScreen(ST77XX_BLACK);
  for (int16_t x=0; x < tft.width(); x+=6) {
    tft.drawLine(tft.width()-1, 0, x, tft.height()-1, color);
    delay(0);
  }
  for (int16_t y=0; y < tft.height(); y+=6) {
    tft.drawLine(tft.width()-1, 0, 0, y, color);
    delay(0);
  }
  tft.fillScreen(ST77XX_BLACK);
  for (int16_t x=0; x < tft.width(); x+=6) {
    tft.drawLine(0, tft.height()-1, x, 0, color);
    delay(0);
  }
  for (int16_t y=0; y < tft.height(); y+=6) {
    tft.drawLine(0, tft.height()-1, tft.width()-1, y, color);
    delay(0);
  }
  tft.fillScreen(ST77XX_BLACK);
  for (int16_t x=0; x < tft.width(); x+=6) {
    tft.drawLine(tft.width()-1, tft.height()-1, x, 0, color);
    delay(0);
  }
  for (int16_t y=0; y < tft.height(); y+=6) {
    tft.drawLine(tft.width()-1, tft.height()-1, 0, y, color);
    delay(0);
  }
}

void testdrawtext(char *text, uint16_t color) {
  tft.setCursor(0, 0);
  tft.setTextColor(color);
  tft.setTextWrap(true);
  tft.print(text);
}

void testfastlines(uint16_t color1, uint16_t color2) {
  tft.fillScreen(ST77XX_BLACK);
  for (int16_t y=0; y < tft.height(); y+=5) {
    tft.drawFastHLine(0, y, tft.width(), color1);
  }
  for (int16_t x=0; x < tft.width(); x+=5) {
    tft.drawFastVLine(x, 0, tft.height(), color2);
  }
}

void testdrawrects(uint16_t color) {
  tft.fillScreen(ST77XX_BLACK);
  for (int16_t x=0; x < tft.width(); x+=6) {
    tft.drawRect(tft.width()/2 -x/2, tft.height()/2 -x/2 , x, x, color);
  }
}

void testfillrects(uint16_t color1, uint16_t color2) {
  tft.fillScreen(ST77XX_BLACK);
  for (int16_t x=tft.width()-1; x > 6; x-=6) {
    tft.fillRect(tft.width()/2 -x/2, tft.height()/2 -x/2 , x, x, color1);
    tft.drawRect(tft.width()/2 -x/2, tft.height()/2 -x/2 , x, x, color2);
  }
}

void testfillcircles(uint8_t radius, uint16_t color) {
  for (int16_t x=radius; x < tft.width(); x+=radius*2) {
    for (int16_t y=radius; y < tft.height(); y+=radius*2) {
      tft.fillCircle(x, y, radius, color);
    }
  }
}

void testdrawcircles(uint8_t radius, uint16_t color) {
  for (int16_t x=0; x < tft.width()+radius; x+=radius*2) {
    for (int16_t y=0; y < tft.height()+radius; y+=radius*2) {
      tft.drawCircle(x, y, radius, color);
    }
  }
}

void testtriangles() {
  tft.fillScreen(ST77XX_BLACK);
  uint16_t color = 0xF800;
  int t;
  int w = tft.width()/2;
  int x = tft.height()-1;
  int y = 0;
  int z = tft.width();
  for(t = 0 ; t <= 15; t++) {
    tft.drawTriangle(w, y, y, x, z, x, color);
    x-=4;
    y+=4;
    z-=4;
    color+=100;
  }
}

void testroundrects() {
  tft.fillScreen(ST77XX_BLACK);
  uint16_t color = 100;
  int i;
  int t;
  for(t = 0 ; t <= 4; t+=1) {
    int x = 0;
    int y = 0;
    int w = tft.width()-2;
    int h = tft.height()-2;
    for(i = 0 ; i <= 16; i+=1) {
      tft.drawRoundRect(x, y, w, h, 5, color);
      x+=2;
      y+=3;
      w-=4;
      h-=6;
      color+=1100;
    }
    color+=100;
  }
}

void tftPrintTest() {
  tft.setTextWrap(false);
  tft.fillScreen(ST77XX_BLACK);
  tft.setCursor(0, 30);
  tft.setTextColor(ST77XX_RED);
  tft.setTextSize(1);
  tft.println("Hello World!");
  tft.setTextColor(ST77XX_YELLOW);
  tft.setTextSize(2);
  tft.println("Hello World!");
  tft.setTextColor(ST77XX_GREEN);
  tft.setTextSize(3);
  tft.println("Hello World!");
  tft.setTextColor(ST77XX_BLUE);
  tft.setTextSize(4);
  tft.print(1234.567);
  delay(1500);
  tft.setCursor(0, 0);
  tft.fillScreen(ST77XX_BLACK);
  tft.setTextColor(ST77XX_WHITE);
  tft.setTextSize(0);
  tft.println("Hello World!");
  tft.setTextSize(1);
  tft.setTextColor(ST77XX_GREEN);
  tft.print(p, 6);
  tft.println(" Want pi?");
  tft.println(" ");
  tft.print(8675309, HEX); // print 8,675,309 out in HEX!
  tft.println(" Print HEX!");
  tft.println(" ");
  tft.setTextColor(ST77XX_WHITE);
  tft.println("Sketch has been");
  tft.println("running for: ");
  tft.setTextColor(ST77XX_MAGENTA);
  tft.print(millis() / 1000);
  tft.setTextColor(ST77XX_WHITE);
  tft.print(" seconds.");
}

void mediabuttons() {
  // play
  tft.fillScreen(ST77XX_BLACK);
  tft.fillRoundRect(25, 10, 78, 60, 8, ST77XX_WHITE);
  tft.fillTriangle(42, 20, 42, 60, 90, 40, ST77XX_RED);
  delay(500);
  // pause
  tft.fillRoundRect(25, 90, 78, 60, 8, ST77XX_WHITE);
  tft.fillRoundRect(39, 98, 20, 45, 5, ST77XX_GREEN);
  tft.fillRoundRect(69, 98, 20, 45, 5, ST77XX_GREEN);
  delay(500);
  // play color
  tft.fillTriangle(42, 20, 42, 60, 90, 40, ST77XX_BLUE);
  delay(50);
  // pause color
  tft.fillRoundRect(39, 98, 20, 45, 5, ST77XX_RED);
  tft.fillRoundRect(69, 98, 20, 45, 5, ST77XX_RED);
  // play color
  tft.fillTriangle(42, 20, 42, 60, 90, 40, ST77XX_GREEN);
}```

LIBRARIES:

Go to Sketch -> Include Library -> Manage Libraries
Search for Adafruit GFX Library and install the latest version and install all the dependencies as well when it asks
Search for Adafruit ST7735 and ST7789 Library and install the latest version and install all the dependencies as well when it asks


text:
avrdude: ser_open(): can't open device "/dev/ttyACM0": Permission denied Upload error:
I am using arduino-ide2.0.0-beta.7(CLI Version:0.18.3 alpha) on Manjaro Linux and I get this error when uploading sketch to my Arduino Micro:

avrdude: ser_open(): can't open device "/dev/ttyACM0": Permission denied
Upload error: Error: 2 UNKNOWN: uploading error: uploading error: exit status 1

I checked other questions and tried:
sudo groupadd dialout
sudo gpasswd -a $USER dialout
sudo chmod a+rw /dev/ttyACM0
sudo usermod -a -G dialout $USER
sudo chown root:dialout -R /dev/
ls -l /dev/ttyACM0 #can see the root:dialout

But when I logout and get again after ls -l /dev/ttyACM0:

crw-rw-rw- 1 root uucp 166, 0  6月 13 17:06 /dev/ttyACM0

So I cannot upload the sketch. Note: I can upload sketches using sudo arduino-ide --no-sandbox , but I want to upload them from the user account.
What else can I try?

https://www.arduino.cc/en/Guide/Linux#please-read

@Juraj I had to run sudo usermod -a -G uucp $USER  instead of sudo usermod -a -G dialout $USER. Thanks.

Instead of:
sudo usermod -a -G dialout $USER

I had to run:
sudo usermod -a -G uucp $USER

Thanks to @Juraj I realized that. Thanks @Juraj.


text:
Connect more than 4 BLE clients to ESP32 BLE Server
I want to create some buzzers connected via bluetooth for a quiz show. I got several ESP32. One of them is the master (BLE Server), the other ESP32s are the buzzers (BLE Clients) with one big button and some LEDs each. The master sends commands ("turn on", "turn off", "you are number x") to all the buzzers and receives when one of them gets pressed.
The code on both sides works for up to 4 clients, but I can't connect more than 4 BLE clients to the BLE server.
I found and changed the CONFIG_BTDM_CONTROLLER_BLE_MAX_CONN and CONFIG_BTDM_CONTROLLER_BLE_MAX_CONN_EFF in sdkconfig.h at C:\Users\MyName\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.4\tools\sdk\include\config.
This seems to be the right place, because both values originally were 3 and then only three clients could connect. The fourth client was rejectet (got a false on pClient->connect(myDevice);). When I updated both numbers to 4, the fourth client could connect and could receive the notifications from the server.
Then I changed these two numbers to 8, because I potentially want to connect even more buzzers. But the 5th buzzer could not connect. It got a true on pClient->connect(myDevice);, but it would not receive any notifications from the server. A few seconds later it starts looking for a server again. The server also does not recognize the 5th client (for client 1 to 4 the server prints Device connected. Now there are x devices connected., but not so for the 5th client)
This is my servers code
#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEServer.h>
#include <BLE2902.h>

#define DEBUG
#define VERSION "0.1"

#define BUZZER_SERVICE_UUID "a2066d3e-d566-42bd-9d64-9bf3ae53b504"
#define COMMAND_CHAR_UUID   "e7adc44d-a04e-46b1-aa4b-ded61bc3b0a8"
#define RESPONSE_CHAR_UUID  "e7adc44d-a04e-46b1-aa4b-ded61bc3b0a9"

#define PIN_BUTTON_ARM 23
#define PIN_BUTTON_DISARM 22

BLEServer* pServer = NULL;
BLECharacteristic* pCommandCharacteristic = NULL;
BLECharacteristic* pResponseCharacteristic = NULL;
int deviceConnected = 0;
bool oldDeviceConnected = false;

bool armPressed = false;
bool disarmPressed = false;

class MyServerCallbacks: public BLEServerCallbacks {
    void onConnect(BLEServer* pServer)
    {
        deviceConnected++;
        BLEDevice::startAdvertising();
        #ifdef DEBUG
        Serial.print("Device connected. Now there are ");
        Serial.print(deviceConnected);
        Serial.println(" devices connected.");
        #endif
    };

    void onDisconnect(BLEServer* pServer)
    {
        deviceConnected--;
        pServer->startAdvertising(); // restart advertising
        #ifdef DEBUG
        Serial.print("Device disconnected. Now there are ");
        Serial.print(deviceConnected);
        Serial.println(" devices connected.");
        #endif
    };
};

class MyCharCallbacks: public BLECharacteristicCallbacks
{
    void onWrite(BLECharacteristic *pCharacteristic)
    {
        std::string rxValue = pCharacteristic->getValue();
        Serial.print(">>> ");
        Serial.println(rxValue.c_str());

        if (rxValue.length() > 0)
        {
            //TODO
        }

    }
};

void setup()
{
    #ifdef DEBUG
    Serial.begin(115200);
    Serial.println("\n\n--------------");
    Serial.println("BUZZER HUB");
    Serial.println("--------------");
    Serial.print("VERSION: ");
    Serial.println(VERSION);
    Serial.println("--------------");
    #endif

    pinMode(PIN_BUTTON_ARM, INPUT_PULLUP);
    pinMode(PIN_BUTTON_DISARM, INPUT_PULLUP);

    BLEDevice::init("BuzzerHub");
    pServer = BLEDevice::createServer();
    pServer->setCallbacks(new MyServerCallbacks());

    BLEService *pService = pServer->createService(BUZZER_SERVICE_UUID);

    // Create a BLE Characteristic and a BLE Descriptor for sending the commands
    pCommandCharacteristic = pService->createCharacteristic(COMMAND_CHAR_UUID, BLECharacteristic::PROPERTY_NOTIFY);
    pCommandCharacteristic->addDescriptor(new BLE2902());

    // Create a BLE Characteristic and a BLE Descriptor for receiving the responses
    pResponseCharacteristic = pService->createCharacteristic(RESPONSE_CHAR_UUID, BLECharacteristic::PROPERTY_WRITE);
    pResponseCharacteristic->addDescriptor(new BLE2902());
    pResponseCharacteristic->setCallbacks(new MyCharCallbacks());

    //Start the service
    pService->start();

    BLEAdvertising *pAdvertising = BLEDevice::getAdvertising();
    pAdvertising->addServiceUUID(BUZZER_SERVICE_UUID);
    pAdvertising->setScanResponse(true);
    pAdvertising->setMinPreferred(0x06);
    BLEDevice::startAdvertising();

    #ifdef DEBUG
    Serial.println("BLE is now advertising");
    #endif
}

void loop()
{
    if(digitalRead(PIN_BUTTON_ARM) == LOW)
    {
        if(!armPressed) //On pressing the button
        {
            armBuzzer();
            delay(100); //Debounce
        }
        armPressed = true;
    }
    else
    {
        if(armPressed) //On releasing the button
        {
            delay(100); //Debounce
        }
        armPressed = false;
    }

    if(digitalRead(PIN_BUTTON_DISARM) == LOW)
    {
        if(!disarmPressed) //On pressing the button
        {
            disarmBuzzer();
            delay(100); //Debounce
        }
        disarmPressed = true;
    }
    else
    {
        if(disarmPressed) //On releasing the button
        {
            delay(100); //Debounce
        }
        disarmPressed = false;
    }
}

void armBuzzer()
{
    if (deviceConnected)
    {
        #ifdef DEBUG
        Serial.println("<<< ARM");
        #endif
        pCommandCharacteristic->setValue("ARM");
        pCommandCharacteristic->notify();
        //delay(3); // bluetooth stack will go into congestion, if too many packets are sent, in 6 hours test i was able to go as low as 3ms
    }
}

void disarmBuzzer()
{
    if (deviceConnected)
    {
        #ifdef DEBUG
        Serial.println("<<< DISARM");
        #endif
        pCommandCharacteristic->setValue("DISARM");
        pCommandCharacteristic->notify();
        //delay(3); // bluetooth stack will go into congestion, if too many packets are sent, in 6 hours test i was able to go as low as 3ms
    }
}

And this is my clients BLE part of the code (there is more, but that got nothing to do with BLE)
// The buzzer service we wish to connect to.
static BLEUUID buzzerServiceUUID("a2066d3e-d566-42bd-9d64-9bf3ae53b504");
// The characteristic of the buzzer service that is there for receiving commands from the hub.
static BLEUUID buzzerCommandCharUUID("e7adc44d-a04e-46b1-aa4b-ded61bc3b0a8");
// The characteristic of the buzzer service that is there for sending commands to the hub.
static BLEUUID buzzerResponseCharUUID("e7adc44d-a04e-46b1-aa4b-ded61bc3b0a9");

static BLERemoteCharacteristic* pCommandCharacteristic;
static BLERemoteCharacteristic* pResponseCharacteristic;
static BLEAdvertisedDevice* myDevice;
String message;
bool newMessage;

static boolean doConnect = false;
static boolean connected = false;

static void notifyCallback(BLERemoteCharacteristic* pBLERemoteCharacteristic, uint8_t* pData, size_t length, bool isNotify)
{
    #ifdef DEBUG
    /*
    Serial.print("Notify callback of data length ");
    Serial.println(length);
    Serial.print("data: ");
    Serial.println((char*)pData);
    */
    #endif
    message = "";
    for(int i = 0; i < length; i++)
    {
        message += (char)pData[i];
    }
    message += '\0';
    newMessage = true;
}

class MyClientCallback : public BLEClientCallbacks {
    void onConnect(BLEClient* pclient)
    {
        connected = true;
        setMiddleLed(0,255,0);
        #ifdef DEBUG
        Serial.println("onConnect");
        #endif
    }

    void onDisconnect(BLEClient* pclient)
    {
        connected = false;
        setMiddleLed(255,0,0);
        updatePattern = false;
        #ifdef DEBUG
        Serial.println("onDisconnect");
        #endif
    }
};

//Scan for BLE servers and find the first one that advertises the service we are looking for.
class MyAdvertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks
{
    //Called for each advertising BLE server.
    void onResult(BLEAdvertisedDevice advertisedDevice)
    {
        #ifdef DEBUG
        Serial.print("Advertised Device found: ");
        Serial.println(advertisedDevice.toString().c_str());
        #endif

        // We have found a device, let us now see if it contains the service we are looking for.
        if (advertisedDevice.haveServiceUUID() && advertisedDevice.isAdvertisingService(buzzerServiceUUID)) // Found our server
        {
            BLEDevice::getScan()->stop();
            myDevice = new BLEAdvertisedDevice(advertisedDevice);
            doConnect = true;
        }
    }
};

bool connectToServer()
{
    #ifdef DEBUG
    Serial.print("Connecting to ");
    Serial.println(myDevice->getAddress().toString().c_str());
    #endif

    //Create Client
    BLEClient*  pClient  = BLEDevice::createClient();
    pClient->setClientCallbacks(new MyClientCallback());

    // Connect to the remote BLE Server.
    bool ok = pClient->connect(myDevice);  // if you pass BLEAdvertisedDevice instead of address, it will be recognized type of peer device address (public or private)
    if (!ok)
    {
        #ifdef DEBUG
        Serial.print("Failed to connect to address: ");
        Serial.println(myDevice->getAddress().toString().c_str());
        #endif
        pClient->disconnect();
        return false;
    }

    // Obtain a reference to the service we are after in the remote BLE server.
    BLERemoteService* pRemoteService = pClient->getService(buzzerServiceUUID);
    if (pRemoteService == nullptr)
    {
        #ifdef DEBUG
        Serial.print("Failed to find our service UUID: ");
        Serial.println(buzzerServiceUUID.toString().c_str());
        #endif
        pClient->disconnect();
        return false;
    }

    // Obtain a reference to the characteristic in the service of the remote BLE server.
    pCommandCharacteristic = pRemoteService->getCharacteristic(buzzerCommandCharUUID);
    if (pCommandCharacteristic == nullptr)
    {
        #ifdef DEBUG
        Serial.print("Failed to find command characteristic UUID: ");
        Serial.println(buzzerCommandCharUUID.toString().c_str());
        #endif
        pClient->disconnect();
        return false;
    }

    // Obtain a reference to the characteristic in the service of the remote BLE server.
    pResponseCharacteristic = pRemoteService->getCharacteristic(buzzerResponseCharUUID);
    if (pResponseCharacteristic == nullptr)
    {
        #ifdef DEBUG
        Serial.print("Failed to find response characteristic UUID: ");
        Serial.println(buzzerResponseCharUUID.toString().c_str());
        #endif
        pClient->disconnect();
        return false;
    }

    //Register the notification
    if(pCommandCharacteristic->canNotify()) pCommandCharacteristic->registerForNotify(notifyCallback);

    return true;
}

void setupBle()
{
    String name = "Buzzer" + String(dipNumber);
    BLEDevice::init(name.c_str());

    scanForServer();
}

void scanForServer()
{
    #ifdef DEBUG
    Serial.println("Scanning for Server...");
    #endif

    setMiddleLed(0,0,255);
    updatePattern = false;

    // Retrieve a Scanner and set the callback we want to use to be informed when we
    // have detected a new device.  Specify that we want active scanning and start the
    // scan to run for 5 seconds.
    BLEScan* pBLEScan = BLEDevice::getScan();
    pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());
    pBLEScan->setInterval(1349);
    pBLEScan->setWindow(449);
    pBLEScan->setActiveScan(true);
    pBLEScan->start(5, false);
}

void loopBle()
{
    // If the flag "doConnect" is true then we have scanned for and found the desired
    // BLE Server with which we wish to connect.  Now we connect to it.
    if (doConnect == true)
    {
        if (connectToServer())
        {
            #ifdef DEBUG
            Serial.println("Connected to server.");
            #endif
        }
        else
        {
            #ifdef DEBUG
            Serial.println("Failed to connect to server.");
            #endif
        }
        doConnect = false;
    }

    if(!connected)
    {
        delay(100);
        setMiddleLed(255,0,0);
        delay(900);
        scanForServer();
    }
}

void sendData(String stringToSend)
{
    // Only send when connected
    if (connected)
    {
        //Set the characteristic's value to be the array of bytes that is actually a string.
        pResponseCharacteristic->writeValue(stringToSend.c_str(), stringToSend.length());
        #ifdef DEBUG
        Serial.print("<<< ");
        Serial.println(stringToSend);
        #endif
    }
    else
    {
        #ifdef DEBUG
        Serial.println("Can't Send because not connected");
        Serial.print("XXX ");
        Serial.println(stringToSend);
        #endif
    }
}

How can I connect more clients to my BLE server? What is the maximum number?

The SDK only allows 4 connections. You might be better off creating a mesh instead, but for that you'd need to switch over to the ESP-IDF.

I've been seeing your posts across the web as I'm trying to create a similar system. Curious as to how you ended up solving this? Did you manage to create a BLE system?

I ended up using the ESPs WiFi instead of BLE if I want more devices coneccted.


text:
When connecting, client.connect() returns 0
I'm using an arduino UNO with ethernet shield. When following a few guides online for a school project I came across this issue. First code sample:

    #include <SPI.h>
    #include <Ethernet.h>

    EthernetClient client;

    byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
    IPAddress ip(192, 168, 1, 25);
    byte server[] = { 64, 233, 187, 99 }; // Google

    void setup() {
      Ethernet.begin(mac, ip);
      Serial.begin(9600);
      delay(1000);
      Serial.println(Ethernet.localIP());
    }

    void loop() {
      if (client.connect(server, 80)) {
        Serial.println("connected");
        client.println("GET /search?q=arduino HTTP/1.0");
        client.println();
      } else {
        Serial.println("connection failed");
        Serial.println(client.connect(server, 80));
      }
    }

This doesn't work, unfortunately. We successfully connect to our network, but client.connect() doesn't work and returns 0. Expected result:

SUCCESS: 1
TIMED_OUT: -1
INVALID_SERVER: -2
TRUNCATED: -3
INVALID_RESPONSE: -4

According to the documentation it shouldn't be able to return this. Why wouldn't this work? Thanks in advance.

dosen't work is not very useful because it does not describe the observed behavior ... what were you expecting client.connect() to return?

one of the values specified in the documentation, which would be: 1, -1, -2, -3 or -4.

The documentation is wrong. The connect function only returns 1 on success and 0 on fail. All examples have if (client.connect(host, port)) { (0 is false, 1 is true).
Try the WebClient example provided in the IDE Examples menu for the Ethernet library. It has better diagnostics of Ethernet link.
You can try the WebServer example. It doesn't need Internet connection.
You can try ping the IP address of the Ethernet shield.
The shield should be connected to a router or switch and the gateway IP address should point to a device routing the network traffic to Internet.

Initialize Ethernet with DHCP:
Failed to configure Ethernet using DHCP
connecting to www.google.com...
connection failed
disconnecting.
Received 0 bytes in 0.0000, rate = 0.00 kbytes/second is the response im getting

this tells us that the shield is detected and the link is active. did you set the IP address and dns server address?

Yes, I set the ip, dns, and gateway to my own

To a switch yes. Ping returns 0% loss.

ok. try the WebServer example. it doesn't need Internet connection

That works. I can connect to the arduino and it shows a webpage

in WebClient example change the server to "arduino.cc" and client.println("GET /asciilogo.txt HTTP/1.1"); as here https://github.com/jandrassy/WiFiEspAT/blob/a2176889757be3fc3cf9c09a1512081864b39111/examples/Basic/WebClient/WebClient.ino#L57

That returns connection failed

use the router's IP address as a gateway. it must be a gateway to Internet

Using the routers IP as a gateway doesnt fix the problem

@SimonV., what are the IP settings of your computer? why your network doesn't have DHCP?

You need to provide more than just the IP address. The Arduino also needs to know the default router address in order to send packets to the right place.
Unfortunately there isn't a way of giving it that information without also giving it a DNS address, so you have to do that as well.
You need to have:
IPAddress gateway(192, 168, 1, 1);
IPAddress dns(8, 8, 8, 8);
IPAddress ip(192, 168, 1, 25);

And then in setup:
Ethernet.begin(mac, ip, dns, gateway);

Alternatively you can rely on DHCP to give you all the details, and just use:
Ethernet.begin(mac);

Unfortunately this does not resolve my issue

I am assuming that your router is 192.168.1.1 - it may not be. You should make sure to use the right IP address there for your network.

the library defaults to gateway and dns calculated from provided IP (last number changed to 1) and net mask 255.255.255.0

I have checked and I am indeed using the correct gateway. Would a powerline adapter influence this? I am using the gateway of the powerline adapter I'm connected to.


text:
Voltage changes but digitalRead always HIGH

I developed a simple push button project
I used a wemos D1 mini
I connected  D3 pin to a pull down 1K resistor.
I used a multimeter to measure D3 pin voltage.

When I push the button, D3 pin voltage changes from 0.x volt to 4.x volt. But digital read on D3 always return HIGH.
Please help me find the problem.
This in my sketch :
    int ledPin = D2; // choose the pin for the LED
    int inPin = D3;   // choose the input pin (for a pushbutton)
    int val = 0;     // variable for reading the pin status

    void setup() {

      pinMode(ledPin, OUTPUT);  // declare LED as output
      pinMode(inPin, INPUT);    // declare pushbutton as input
    }

    void loop(){

      val = digitalRead(inPin);  // read input value
      if (val == HIGH) {
        digitalWrite(ledPin, LOW);
      } else {
        digitalWrite(ledPin, HIGH);
      }
    }

How can it be that you measure > 4V at D3 if you're just pulling down the pin. Either you provide us with schematics on what's at D3 or we won't be able to do anything else than speculate, let alone help you.

you should use the INPUT_PULLUP mode if you want to activate by connecting the GPIO to GND; otherwise your input state will be inverted.

The problem is that when the button isn't pressed, the voltage at pin D3 is just floating. Since there is nothing attached, the voltage at the pin can be anything. To prevent this, you use a pull-down resistor, so that when the button isn't pressed, the voltage at D3 is pulled to ground, and you will get a LOW using digitalRead.

simulate this circuit – Schematic created using CircuitLab

First of all - read your post before you actually post it. This code is no readable. And if you have problems with electronics add picture of schematics how you connected your board. There can be problem too.

D3    IO, 10k Pull-up GPIO0

Source: https://www.wemos.cc/product/d1-mini-pro.html
Your D3 pin have internally pull-up so no doubt that it reads HIGH all the time. Connect your board like on picture below or change your reading pin to D0 for example (It has no other function than simple IO).

simulate this circuit – Schematic created using CircuitLab
For this case you can trust internal pull-up but in more complicated projects you should add your own one.
For more information about pull-ups and pull-downs check this article: http://www.electronics-tutorials.ws/logic/pull-up-resistor.html

Thanks for your advice Adam Rosiek, i choose D3 for some packaging space issue. Yes i move to D8 it solve the problem. And i.m sorry for inconvenient code and no picture

authors: Александр Гриневич


text:
Difficulty with shifting data
Im trying to shift LEDs using 595 register. Using SN74HC595N registers. Im using 4 of the registers as i got alots of LEDs to shift. My code for shifting doesn't seem working.. i can shift some with 2 registers but not 4 registers
// include the library code:
#include <LiquidCrystal.h>
#include <Wire.h>
#include "RTClib.h"

RTC_DS1307 RTC;

// initialize the library with the numbers of the interface pins
// RS-12, E-13, D4-8, D5-9, D6-10, D7-11
LiquidCrystal lcd(12, 13, 8, 9, 10, 11);

int row[]={8,9,10,11};// Digital output connect directly to all rows
int col[] = {A0,A1,A2}; // Analog input with 10K pull-up to 5V.
int i,j; // Two counter variables to count inside for loop
int col_scan; // Variable to hold value of scanned columns

//Pin connected to ST_CP of 74HC595
int latchPin = 3;
//Pin connected to SH_CP of 74HC595
int clockPin = 4;
////Pin connected to DS of 74HC595
int dataPin = 5;

//holder for infromation you're going to pass to shifting function
byte data = 0;
byte data1 = 0x55;
byte data2 = 0xAA;

void setup()
{
  Wire.begin();
  RTC.begin();
  Serial.begin(9600);
  for(i=0;i<=3;i++)
  {
    pinMode(row[i],OUTPUT);
    //pinMode(col[i],INPUT);
    //digitalWrite(col[i],HIGH);
  }

  // set up the LCD's number of columns and rows:
  lcd.begin(16, 2);
  // Print a message to the LCD.
  lcd.print("Medicine Box");

  //set pins to output because they are addressed in the main loop
  pinMode(latchPin, OUTPUT);

  if (! RTC.isrunning())
  {
    Serial.println("RTC is NOT running!");
    // following line sets the RTC to the date & time this sketch was compiled
    RTC.adjust(DateTime(__DATE__, __TIME__));
  }

  for (i=0;i<=4; i++)
  {
    digitalWrite(latchPin, 0);
    shiftOut(dataPin, clockPin, data1);
    shiftOut(dataPin, clockPin, data1);
    digitalWrite(latchPin, 1);
    delay(500);
    digitalWrite(latchPin, 0);
    shiftOut(dataPin, clockPin, data2);
    shiftOut(dataPin, clockPin, data2);
    digitalWrite(latchPin, 1);
    delay(500);
  }
}

void loop()
{

  DateTime now = RTC.now();
  // set the cursor to column 0, line 1
  // (note: line 1 is the second row, since counting begins with 0):
  lcd.setCursor(0, 1);
  // print the number of seconds since reset:
  //lcd.print(millis() / 1000);
  //Serial.println(now);
  //Serial.print("    ");
   /*   Serial.print(now.day(), DEC);
      Serial.print('/');
      Serial.print(now.month(), DEC);
      Serial.print('/');
      Serial.print(now.year(), DEC);
      Serial.print(' ');
      Serial.print(now.hour(), DEC);
      Serial.print(':');
      Serial.print(now.minute(), DEC);
      Serial.print(':');
      Serial.print(now.second(), DEC);
      Serial.println(" ");*/

      lcd.print(now.day(), DEC);
      lcd.print('/');
      lcd.print(now.month(), DEC);
      lcd.print('/');
      lcd.print(now.year()-2000, DEC);
      lcd.print(' ');
      if (now.hour()<10)
        lcd.print('0');
      lcd.print(now.hour(), DEC);
      lcd.print(':');
      if (now.minute()<10)
        lcd.print('0');
      lcd.print(now.minute(), DEC);
      lcd.print(':');
      if (now.second()<10)
        lcd.print('0');
      lcd.print(now.second(), DEC);
      //lcd.println(" ");

  for(i=0; i<=3; i++)
  {
    digitalWrite(row[0],HIGH);
    digitalWrite(row[1],HIGH);
    digitalWrite(row[2],HIGH);
    digitalWrite(row[3],HIGH);
    digitalWrite(row[i],LOW);

    for(j=0; j<=2; j++)
    {
      col_scan=analogRead(col[j]);
      if(col_scan < 1000)
      {
        while(analogRead(col[j])< 1000);
        keypress(i,j);
      }
    }
  }
  digitalWrite(latchPin, 0);
  shiftOut(dataPin, clockPin, data1);
  shiftOut(dataPin, clockPin, data1);
  digitalWrite(latchPin, 1);
}

void keypress(int i, int j)
{
  if(i==0&&j==0)
    Serial.println("1");
  else if(i==0&&j==1)
    Serial.println("2");
  else if(i==0&&j==2)
    Serial.println("3");
  else if(i==0&&j==3)
    Serial.println("A");
  else if(i==1&&j==0)
    Serial.println("4");
  else if(i==1&&j==1)
    Serial.println("5");
  else if(i==1&&j==2)
    Serial.println("6");
  else if(i==1&&j==3)
    Serial.println("B");
  else if(i==2&&j==0)
    Serial.println("7");
  else if(i==2&&j==1)
    Serial.println("8");
  else if(i==2&&j==2)
    Serial.println("9");
  else if(i==2&&j==3)
    Serial.println("C");
  else if(i==3&&j==0)
    Serial.println("*");
  else if(i==3&&j==1)
    Serial.println("0");
  else if(i==3&&j==2)
    Serial.println("#");
  else if(i==3&&j==3)
    Serial.println("D");
}

// the heart of the program
void shiftOut(int myDataPin, int myClockPin, byte myDataOut) {
  // This shifts 8 bits out MSB first,
  //on the rising edge of the clock,
  //clock idles low

  //internal function setup
  int i=0;
  int pinState;
  pinMode(myClockPin, OUTPUT);
  pinMode(myDataPin, OUTPUT);

  //clear everything out just in case to
  //prepare shift register for bit shifting
  digitalWrite(myDataPin, 0);
  digitalWrite(myClockPin, 0);

  //for each bit in the byte myDataOut�
  //NOTICE THAT WE ARE COUNTING DOWN in our for loop
  //This means that %00000001 or "1" will go through such
  //that it will be pin Q0 that lights.
  for (i=7; i>=0; i--)  {
    digitalWrite(myClockPin, 0);

    //if the value passed to myDataOut and a bitmask result
    // true then... so if we are at i=6 and our value is
    // %11010100 it would the code compares it to %01000000
    // and proceeds to set pinState to 1.
    if ( myDataOut & (1<<i) ) {
      pinState= 1;
    }
    else {
      pinState= 0;
    }

    //Sets the pin to HIGH or LOW depending on pinState
    digitalWrite(myDataPin, pinState);
    //register shifts bits on upstroke of clock pin
    digitalWrite(myClockPin, 1);
    //zero the data pin after shift to prevent bleed through
    digitalWrite(myDataPin, 0);
  }

  //stop shifting
  digitalWrite(myClockPin, 0);
}

My code for shifting doesn't seem working. - this is not a helpful description. What happens? Too many LEDs light up? Too few? They change randomly? The program stops doing anything? "Not working" can mean anything. Try ringing your local garage and saying your car is "not working" - they will soon start asking you if you are having trouble starting it, steering it, if the radio is working, if the tyres are flat, etc.

Why implement your own shiftOut, when it already exists and is more efficient than yours, besides? Theres no need to 'zero out' the data pin after raising the clock HIGH; how do you even know that the register has read the bit you just sent? Read about 'Hold time'.

Your code looks unnecessarily convoluted for merely sending data to a shift register. You can use the SPI hardware for that.
For example:
#include <SPI.h>

const byte LATCH = 10;

void setup ()
{
  SPI.begin ();
}  // end of setup

void loop ()
{
  digitalWrite (LATCH, LOW);
  SPI.transfer (0xAB);
  SPI.transfer (0xCD);
  SPI.transfer (0xEF);
  SPI.transfer (0x42);
  digitalWrite (LATCH, HIGH);
  delay (20);
}  // end of loop

You have to use the SPI hardware pins for this to work. On a Uno these are:

Chip pin 14 (DS) goes to MOSI  (D11)
Chip pin 11 (SH) goes to SCK   (D13)
Chip pin 12 (ST) goes to SS    (D10)  (or any other pin by changing LATCH)

Example wiring:

More details on my page about the 595 chip.