text:
Running full voltage through Transistors
Hello I am trying to create a fan controller using Arduino. The (Placeholder LED's) fans run at 12V 0.23A DC so I have an external power supply for them. I plan to control the flow of this with NPN Transistors.
But before I build it I am running it in a simulator. And I am having an issue where at times, none of the power supply's voltage is going through the transistors and other times its in parallel and the voltage across all three drops down to 4.12V.
Is there any way to run these in series to keep the same voltage? And if why the power supply's voltage is being ignored at times.

I don't think my code will be needed but in case I will have it below.
    //#include <DHT.h>
    //#include <DHT_U.h>
    //#include <Adafruit_Sensor.h>
    #include <Wire.h>
    #include <LiquidCrystal_I2C.h>
    LiquidCrystal_I2C lcd(0x27, 16, 2);

    //#define DHTPIN A0
    //#define DHTTYPE DHT11
    //DHT dht(DHTPIN, DHTTYPE);

    unsigned long time = 0;
    unsigned long debounce = 200UL;

    float(value);
    int Temp = 0;
    int tmp = A0;

    int fan1State = 0;
    int fan2State = 0;
    int fan3State = 0;
    int fansOn = 0;

    int fanOne = 5;
    int fanTwo = 6;
    int fanThree = 7;
    int bF1 = 2;
    int bF2 = 3;
    int bF3 = 4;

    int oldbFState1;
    int oldbFState2;
    int oldbFState3;

    int bFState1;
    int bFState2;
    int bFState3;

    int bCount = 0;

    int dispA = 13;
    int dispB = 12;
    int dispC = 10;
    int dispD = 9;
    int dispE = 8;
    int dispG = 11;

    void setup(){

      pinMode(dispA, OUTPUT);
      pinMode(dispB, OUTPUT);
      pinMode(dispC, OUTPUT);
      pinMode(dispD, OUTPUT);
      pinMode(dispE, OUTPUT);
      pinMode(dispG, OUTPUT);

      pinMode(tmp, INPUT);
      pinMode(fanOne, OUTPUT);
      pinMode(fanTwo, OUTPUT);
      pinMode(fanThree, OUTPUT);
      pinMode(bF1, INPUT_PULLUP);
      pinMode(bF2, INPUT_PULLUP);
      pinMode(bF3, INPUT_PULLUP);

      Serial.begin(9600);

      lcd.begin(16,2);
      lcd.init();
      lcd.backlight();
      lcd.setCursor(0,0);
      lcd.print("Hello World.");
      delay(2000);
      lcd.setCursor(0,1);
      lcd.print("Boot Done.");
    }

    void loop(){

      //Temp = (analogRead(tmp)*(3300/1024));
      //lcd.setCursor(0,0);
      //lcd.print("Temperature: ");
      //lcd.print(Temp);

        // SEVEN SEGMENT DISPLAY.

      if (bCount >= 0) {

        if (bCount == 1) {
          digitalWrite(dispA, LOW);
          digitalWrite(dispB, HIGH);
          digitalWrite(dispC, HIGH);
          digitalWrite(dispD, LOW);
          digitalWrite(dispE, LOW);
          digitalWrite(dispG, LOW);
        }
        if (bCount == 2) {
          digitalWrite(dispA, HIGH);
          digitalWrite(dispB, HIGH);
          digitalWrite(dispC, LOW);
          digitalWrite(dispD, HIGH);
          digitalWrite(dispE, HIGH);
          digitalWrite(dispG, HIGH);
        }
        if (bCount == 3) {
          digitalWrite(dispA, HIGH);
          digitalWrite(dispB, HIGH);
          digitalWrite(dispC, HIGH);
          digitalWrite(dispD, HIGH);
          digitalWrite(dispE, LOW);
          digitalWrite(dispG, HIGH);
        }
        else {
          digitalWrite(dispA, LOW);
          digitalWrite(dispB, LOW);
          digitalWrite(dispC, LOW);
          digitalWrite(dispD, LOW);
          digitalWrite(dispE, LOW);
          digitalWrite(dispG, LOW);
        }
      }
        // FAN CONTROL CODE LIES BELOW

      int bFState1 = digitalRead(bF1);
      int bFState2 = digitalRead(bF2);
      int bFState3 = digitalRead(bF3);

      // Ehaust Fan 1

      if (bFState1 == HIGH && oldbFState1 == LOW) {

        if (fan1State == 0) {
          digitalWrite(fanOne, HIGH);
          Serial.println("B1 ON");
          lcd.clear();
          lcd.setCursor(0,0);
          lcd.print("Ehaust Fan On.");
          fan1State = 1;
          bCount = (bCount + 1);
          delay(1000);
          lcd.clear();

        } else {
          digitalWrite(fanOne, LOW);
          Serial.println("B1 OFF");
          lcd.clear();
          lcd.setCursor(0,0);
          lcd.print("Ehaust Fan Off.");
          fan1State = 0;
          bCount = (bCount - 1);
          delay(1000);
          lcd.clear();

        }
      }

      oldbFState1 = bFState1;

      // Intake Fan 2

      if (bFState2 == HIGH && oldbFState2 == LOW) {

        if (fan2State == 0) {
          digitalWrite(fanTwo, HIGH);
          Serial.println("B2 ON");
          lcd.clear();
          lcd.setCursor(0,0);
          lcd.print("Intake Fan 1 On.");
          fan2State = 1;
          bCount = (bCount + 1);
          delay(1000);
          lcd.clear();

        } else {
          digitalWrite(fanTwo, LOW);
          Serial.println("B2 OFF");
          lcd.clear();
          lcd.setCursor(0,0);
          lcd.print("Intake Fan 1 Off.");
          fan2State = 0;
          bCount = (bCount - 1);
          delay(1000);
          lcd.clear();

        }
      }

      oldbFState2 = bFState2;

      // Intake Fan 3

      if (bFState3 == HIGH && oldbFState3 == LOW) {

        if (fan3State == 0) {
          digitalWrite(fanThree, HIGH);
          Serial.println("B3 ON");
          lcd.clear();
          lcd.setCursor(0,0);
          lcd.print("Intake Fan 2 On.");
          fan3State = 1;
          bCount = (bCount + 1);
          delay(1000);
          lcd.clear();

        } else {
          digitalWrite(fanThree, LOW);
          Serial.println("B3 OFF");
          lcd.clear();
          lcd.setCursor(0,0);
          lcd.print("Intake Fan 2 Off.");
          fan3State = 0;
                  bCount = (bCount - 1);
          delay(1000);
          lcd.clear();

        }
      }

      oldbFState3 = bFState3;
    }

Why is ground of the fan power supply connected to the 3.3V pin of the Arduino? Should that be also ground? Also typically one would include resistors for the LEDs of the 7 Segment display (and technically also the placeholder LEDs) and a fitting one at the base of the transistor, so that no component gets destroyed due to too much current.

What exactly does "at times" mean? Randomly between individual simulation runs? And what do you mean by parallel and series in this case?

Well the ground cable was not supposed to go there. That was a mistake, But the two boards need to share a ground otherwise the Base of the transistor doesn't seem to take input.
Yes in-between simulations at times the power supply just doesn't work.

LEDs are not appropriate placeholders for fans. They behave completely differently. Your transistors need base resistors as to not overload your Arduino's GPIO pins and the fans (when implemented) should have flyback diodes because they are inductive loads.

At the moment I believe the transistors are in parallel since the voltage out the emitter is only around 4v. And for the fans to spin at a decent speed to move air I need the entire 12v output from the power supply.

Like this?
UpdatedTransistorBoard

Also, the loads (LEDs / fans) should be placed on the "high side". i.e. not between emitter and ground, but between P1+ (12V power rail) and emitter.

Per recommendation I changed out the LED's for DC motors I probably should've done that from the start but I just didn't think of the fact that the LED's weren't good stand ins thank you for that. The power supply not working between simulations might of just been a bug on tinkercad's since It seems to be fine now. However the motors are running in parallel still and only getting 3~4V which doesn't give them good rotation.

Tinkercad_Screenshot
Technical_Drawing_Motors

There is too much going on here. Remove everything that is not related to your current problem (LCD, 7-segment display, buttons) and keep just one motor. Once you have something that works reliably, you can add the missing stuff.

Here is how you drive an inductive load with an Arduino and an NPN
transistor:

simulate this circuit – Schematic created using CircuitLab
Please, note the common ground, the resistor on the base of the
transistor, the flyback diode, and the fact that the transistor is
mounted as a low-side switch.

Thank you for this diagram. I made a seperate circuit with just a singular motor following this and it worked flawlessly.

However when I add the other motors alongside the voltage drops to almost nothing meaning only one fan can run at a time.

Is the solution for this just a higher power supply and voltage regulators or can this be done with fancy wiring?

@Ironshi: Yous should be able to drive this way as many motors as you want. If the supply voltage drops, that's because you are exceeding the capacity of the power supply. Or maybe because it is a lab bench supply and you configured it to not deliver more than some specified maximum current.

I see it may be the limitations of the programs power supply then, Thank you for the help.


text:
Connecting 3x 0.91Oleds (Using a TCA9548A 8-channel multiplex) and 1 1.51 Inch Transperant SPI OLED
As the title suggests, I have an Arduino Nano connected to a multiplex (which is connected to 3x 0.91 OLEDs) and an 1.51 inch OLED connected through an SPI.
The problem is that they just refuse to work simultaneously - both work, I've tested them independently. However, when writing code for both, the second part to be initialized always fails. If I initialize the 1.51 OLED first it works and the 3x multiplex 0.91 fails and vise versa.
Here's my code:
#include <Wire.h>
#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define SCREEN_WIDTH_T 128
#define SCREEN_HEIGHT_T 64

#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 32
#define OLED_RESET -1
#define OLED_ADDR 0x3C
#define TCA9548A_ADDR 0x70

#define OLED_MOSI 11
#define OLED_CLK 13
#define OLED_DC 8
#define OLED_CS 10
#define OLED_RESET_SPI 9

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
Adafruit_SSD1306 displayO(SCREEN_WIDTH_T, SCREEN_HEIGHT_T, OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET_SPI, OLED_CS);

void tcaSelect(uint8_t i) {
  if (i > 7) return;
  Wire.beginTransmission(TCA9548A_ADDR);
  Wire.write(1 << i);
  Wire.endTransmission();
}

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

  delay(100);

  if (!displayO.begin(SSD1306_SWITCHCAPVCC, 0x3D)) {
    Serial.println(F("SSD1306 allocation failed for SPI OLED"));
    while (1);
  }
  displayO.display();
  delay(200);
  displayO.clearDisplay();
  displayO.drawPixel(10, 10, SSD1306_WHITE);
  displayO.display();
  delay(200);

  // Initialize I2C displays on the multiplexer
  for (uint8_t i = 0; i < 3; i++) {
    tcaSelect(i);
    delay(100);
    if (!display.begin(SSD1306_SWITCHCAPVCC, OLED_ADDR)) {
      Serial.print(F("SSD1306 allocation failed for display on channel "));
      Serial.println(i + 1);
    } else {
      display.clearDisplay();
      display.setTextSize(1);
      display.setTextColor(SSD1306_WHITE);
      display.setCursor(0, 0);
      display.print(F("Hello World\nScreen "));
      display.print(i + 1);
      display.print(F("/3"));
      display.display();
      delay(1000);
    }
  }

  // Initialize SPI OLED display

}

void loop() {
  displayO.clearDisplay();
  displayO.setTextSize(1);
  displayO.setTextColor(SSD1306_WHITE);
  displayO.setCursor(0, 0);
  displayO.println(F("Hello, world!"));
  displayO.display();
  delay(2000);
}

In this example the 1.51 OLED (display0) initializes fine, however the other 3 displays fail.
If I switch some code around (placing display0 code below the display code) then the 3x OLEDs work and display0 fails.
I've been trying to solve this for ages and I got no idea what is causing this failure, please save me.

There may be pin conflicts arising somewhere. Make sure there are no conflicts between the SPI and I2C libraries.

i really got no idea, the multiplex sits on the A5 and A4 pins while the SPI sits on D9-D13 pins, theoretically it shouldnt be an issue (although i dont really know enough to be sure). every single check i ran (I2C port scans and the such) never returned any errors.
Eventually i gave up and went with adafruit for the Multiplex OLEDS and SSD1306Ascii for the SPI.
it is ugly, but it works, suboptimaly.

Are you not receiving the messages telling you that allocation failed?

Yeah, i do get the "Allocation failed" messages when it tries to initialize.

So, you've confirmed the failed-to-initialize in a comment that said:

Yeah, i do get the "Allocation failed" messages when it tries to initialize

When I build your code with what I have here for an environment:
Wire                 1.0     /home/user/.arduino15/packages/arduino/hardware/avr/1.8.7/libraries/Wire
SPI                  1.0     /home/user/.arduino15/packages/arduino/hardware/avr/1.8.7/libraries/SPI
Adafruit GFX Library 1.11.9  /home/user/Arduino/libraries/Adafruit_GFX_Library
Adafruit BusIO       1.15.0  /home/user/Arduino/libraries/Adafruit_BusIO
Adafruit SSD1306     2.5.9   /home/user/Arduino/libraries/Adafruit_SSD1306

it says:
Global variables use 587 bytes (28%) of dynamic memory, leaving 1461 bytes for local variables. Maximum is 2048 bytes.

By which "dynamic memory" doesn't mean what's conventionally meant by "dynamic memory" (dynamically allocated memory)  They're referring to SRAM (changeable thus "dynamic" memory) which includes both things like global variables but also normal string literals on the nano an other things.
The compiler knows that 587 bytes are flatly needed no matter what happens at runtime. You have 1461 remaining and are attempting to use one instance of Adafruit_SSD1306 for a 128x64 resolution display and second instance for multiple 128x32 resolution display. Using a single instance to control three displays is probably not something expected by Adafruit, but I'm not overly surprised that part at least appears to work.
The problem is that you are simply running out of memory, as the message you're receiving indicates. These are 1-bit-per-pixel display. So you need 128x32 and 128x64 bits at the same time. You can see this calculation being done in the Adafruit library. That's 128 * 4 and 128 * 8 bytes respectively. Or 512 bytes and 1024 bytes. Or 1536 bytes in total (just for the display buffer) So that already doesn't fit in 1461 bytes you have at start of runtime, nevermind the stack/local variables and some other things allocated at runtime (e.g Serial buffers) that are going to be in SRAM. So you are simply not going to be able to have both instances of Adafruit_SSD1306 for 128x32 and 128x64 resolutions at the same time still have enough memory left to function on an ATmege328P. Realistically you should probably get a larger chip.
But, you can try writing your code such that you only have one instance of either created at any given moment. Probably the simplest way to do this is to have functions that draw to the x32 and x64 displays and have the Adafruit_SSD1306 object be a local variable in that function, so that when the function exits after drawing a frame the dynamic memory it was using gets freed. The downside is you'd be re-initalizing the display on every frame on recreation of the Adafruit_SSD1306 object, but that may not be a problem. It may flicker or something to that effect. You'd need to test.
So your functions would take a form similar to:
void display_on_spi_x64() {
  Adafruit_SSD1306 display(SCREEN_WIDTH_T, SCREEN_HEIGHT_T, OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET_SPI, OLED_CS);
  if (!display.begin(SSD1306_SWITCHCAPVCC)) {
    Serial.println(F("SSD1306 allocation failed for SPI OLED"));
    while (1);
  }
  display.clearDisplay();
// various display.drawWhatever(); calls.
  display.display();
}

void display_on_i2c_x32(int display_i2c_mux_channel) {
  tcaSelect(display_i2c_mux_channel);
  Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
  if (!display.begin(SSD1306_SWITCHCAPVCC, OLED_ADDR)) {
    Serial.print(F("SSD1306 allocation failed for I2C display on channel "));
    Serial.println(display_i2c_mux_channel + 1);
    while (1);
  }
  display.clearDisplay();
// various display.drawWhatever(); calls.
  display.display();
}

I have not tested the above. It is only a guide.
So the Adafruit_SSD1306 instances only live while the function has been entered and die when the function ends. And when that happens the ram for the display buffer is freed. Nothing else is asked of the display, so it should retain the last image given to it even after the Adafruit_SSD1306 object dies when the function exits.
In theory the Adafruit_SSD1306 library could be modified so that you provide your own buffer of at least the minimum required size during begin() rather than allowing begin() to allocate it internally as the library currently does via malloc(). If you used your own buffer, you'd share that among the four instances of Adafruit_SSD1306 with the caveat that you need to re-render the entire frame when switching between devices. Though you're already subject to that restriction because of how you're using the single Adafruit_SSD1306 instance to control three I2C displays.
Another library (maybe u8g2) may already support this. Failing that, get an Arduino with more RAM. During usage of the 128x64 display, you will have less than 2048-1024-587 or 437 bytes of SRAM for stack/locals, Serial buffers and so on. It would not surprise me that a project using four displays like this would need more than 437 bytes to do all of the non-display related stuff. I believe u8g2 is able to use 512 bytes of ram when working with an 128x64 SSD1306 display through its multiple passes during the drawing phase. So, you may want to use u8g2 just to reclaim some SRAM even if you end up adopting the same strategy above of creating and destroying instances u8g2 displays object instead. Or again, get a bigger Arduino.

source: Stack Exchange

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

sort: votes


text:
Error trying to play audio through an ESP8266 using the 'ESP8266Audio' library
I am attempting to use an esp8266 to play an .mp3 audio file through a connected speaker using the 'ESP8266Audio' library.
I have tested that the hardware setup is correct (e.g. I have been able to play sounds from the speaker using a simple tone() function). I have also tested that the filesystem image is correctly built and uploaded because I have been able to list the files in the directory and read from simple text files that I have placed there.
Why is my code unable to process/play the audio file?
Here is my code:
    #include <Arduino.h>
    #include <LittleFS.h>
    #include <AudioFileSourceLittleFS.h>
    #include <AudioGeneratorMP3.h>
    #include <AudioOutputI2SNoDAC.h>

    AudioGeneratorMP3 *mp3;
    AudioFileSourceLittleFS *file;
    AudioOutputI2SNoDAC *out;

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

        if (!LittleFS.begin()) {
            Serial.println("LittleFS initialization failed!");
            return;
        } else {
            Serial.println("LittleFS initialisation successful");
        }

        file = new AudioFileSourceLittleFS("/feet.mp3");
        if (!file->isOpen()) {
            Serial.println("Failed to open file.");
            return;
        } else {
            Serial.println("File opened successfully.");
        }

        out = new AudioOutputI2SNoDAC();
        out->SetOversampling(200);
        out->SetGain(2.0);

        mp3 = new AudioGeneratorMP3();
        if (mp3->begin(file, out)) {
            Serial.println("MP3 begin successful");
        } else {
            Serial.println("MP3 begin failed");
        }
    }

    void loop() {

        if (mp3->isRunning()) {
            if (!mp3->loop()) {
                Serial.println("MP3 loop failed");
                mp3->stop();
            } else {
                Serial.print("Free heap during loop: ");
                Serial.println(ESP.getFreeHeap());
            }
        } else {
            Serial.println("MP3 done");
            delay(1000);
        }
    }

The results of the exception decoder is:
    Exception (3):
    epc1=0x402046ae epc2=0x00000000 epc3=0x00000000 excvaddr=0x40249b36 depc=0x00000000

    LoadStoreError: Processor internal physical address or data error during load or store
      epc1=0x402046ae in mad_layer_III at ??:?
      excvaddr=0x40249b36 in system_get_sdk_version at ??:?

   >>>stack>>>

    ctx: cont
    sp: 3ffffb40 end: 3fffffd0 offset: 0150
    3ffffc90:  00000000 00000000 00000000 006f0000
    3ffffca0:  00000000 00000000 0000f884 00000000
    3ffffcb0:  00000000 00000000 00000000 00000000
    3ffffcc0:  00000000 00000030 00000008 3ffe8368
    3ffffcd0:  4025dd3f 3ffe8368 40219f3c 00000004
    3ffffce0:  00000000 0000000a 3ffffd53 00000000
    3ffffcf0:  000000b0 00000000 3ffffd53 4025e128
    3ffffd00:  4025e129 3ffe8368 3ffffdc0 02b2a450
    3ffffd10:  009200c0 01000000 00ff050f 24070000
    3ffffd20:  00000004 00000039 fe302064 3ffef64c
    3ffffd30:  00100408 3ffef9c0 00100408 00000000
    3ffffd40:  00000000 00000000 0000001f 341002a8
    3ffffd50:  00353930 400042db 3fffc228 40105af5
    3ffffd60:  40004b31 3ffefa14 00000000 003435c0
    3ffffd70:  3ffffe90 3ffffe80 00000014 4000050c
    3ffffd80:  3ffffe90 ffffff9d ffffff9d ffffff9d
    3ffffd90:  ffffff9d ffffff9d ffffff9d ffffff9d
    3ffffda0:  ffffff9d ffffff9d ffffff9d ffffff9d
    3ffffdb0:  ffffff9d ffffff9d ffffff9d ffffff9d
    3ffffdc0:  ffffff9d ffffff9d ffffff9d ffffff9d
    3ffffdd0:  ffffff9d ffffff9d ffffff9d 3ffe85e0
    3ffffde0:  00000080 0000270f 00000000 00000030
    3ffffdf0:  402079a8 00000030 00000008 ffffffff
    3ffffe00:  402079a8 3fff12eb 3ffefa30 00000001
    3ffffe10:  40100175 00000096 3ffefa30 00000001
    3ffffe20:  4000050c 40100138 3fffc270 4000050c
    3ffffe30:  40100175 00000080 3fff0374 402174cd
    3ffffe40:  3ffffe90 3ffffe80 0000000c 4000050c
    3ffffe50:  4020b8f8 00000030 00000008 ffffffff
    3ffffe60:  3fff0d04 00080010 40252660 40217540
    3ffffe70:  3fff536c 3fff5c6c 3fff0d01 00080010
    3ffffe80:  ffffffe8 14000000 04000000 3ffffc90
    3ffffe90:  40252664 3ffffd88 00000000 00000001
    3ffffea0:  00000000 3fff1d3c 00000002 3ffffc90
    3ffffeb0:  00000000 00000000 3ffffe68 3fff536c
    3ffffec0:  00000000 00000000 000002b2 3fff12f4
    3ffffed0:  3fff1cf4 74612027 00000001 40251be4
    3ffffee0:  74657366 3ffffc90 00000054 00000000
    3ffffef0:  000000ab 3fff1324 00000057 00000057
    3fffff00:  00000054 000000ab 00000004 3fff5c6c
    3fffff10:  3fff1d3c 00000002 3fffff6c 3fff12f4
    3fffff20:  00000001 3fff1d3c 3fff1310 4020158f
    3fffff30:  3fff12ec 00000000 6f726863 617a696e
    3fffff40:  3fff12ec 00000001 3fff0374 00000000
    3fffff50:  3fff1cf4 3fff12f4 3fff1d3c 402016b8
    3fffff60:  0000270f 3fff0374 00000000 4020db7c
    3fffff70:  0000270f 3fff0384 3fff0374 4020d004
    3fffff80:  0000270f 3fff0384 3fff0374 4020d161
    3fffff90:  4020f19c 3ffe8b88 3ffee8fc 3ffeea6c
    3fffffa0:  3fffdad0 3ffee8bc 3ffee8fc 4020c34f
    3fffffb0:  3fffdad0 00000000 3ffeea40 402107bc
    3fffffc0:  feefeffe feefeffe 3fffdab0 40100f11
    <<<stack<<<

    0x4025dd3f in etharp_output at ??:?
    0x40219f3c in __ssputs_r at /workdir/repo/newlib/newlib/libc/stdio/nano-vfprintf.c:179
    0x4025e128 in etharp_output at ??:?
    0x4025e129 in etharp_output at ??:?
    0x40105af5 in ets_timer_disarm at ??:?
    0x402079a8 in lfs_bd_read at lfs.c:?
    0x402079a8 in lfs_bd_read at lfs.c:?
    0x40100175 in i2s_slc_isr at core_esp8266_i2s.cpp:?
    0x40100138 in i2s_slc_isr at core_esp8266_i2s.cpp:?
    0x40100175 in i2s_slc_isr at core_esp8266_i2s.cpp:?
    0x402174cd in vsnprintf at /workdir/repo/newlib/newlib/libc/stdio/vsnprintf.c:41
    0x4020b8f8 in lfs_file_read at ??:?
    0x40252660 in system_get_sdk_version at ??:?
    0x40217540 in snprintf_P at /workdir/repo/newlib/newlib/libc/sys/xtensa/stdio_pgmspace.c:33
    0x40252664 in system_get_sdk_version at ??:?
    0x40251be4 in system_get_sdk_version at ??:?
    0x4020158f in mad_header_decode at ??:?
    0x402016b8 in mad_frame_decode at ??:?
    0x4020db7c in littlefs_impl::LittleFSFileImpl::read(unsigned char*, unsigned int) at ??:?
    0x4020d004 in AudioGeneratorMP3::DecodeNextFrame() at ??:?
    0x4020d161 in AudioGeneratorMP3::loop() at ??:?
    0x4020f19c in HardwareSerial::write(unsigned char const*, unsigned int) at ??:?
    0x4020c34f in loop at ??:?
    0x402107bc in loop_wrapper() at core_esp8266_main.cpp:?
    0x40100f11 in cont_wrapper at ??:?

As an newbie to this world, any help would be greatly appreciated!

What messages appeared on the console before the stack trace ?

I found the source of my problems was that the most up to date version of the ESP8266Audio library (1.9.9) does not seem to be compatible with my setup.
Reverting back to a previous revision of the library (1.9.7)

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


text:
3.5 inch TFT LCD connection diagram with mega r3
Forum post
I would like to ask if someone has this shield fully working?
My biggest problem is the touch screen that I couldn't manage to make work.
Here is the code I am using:
// ic: ili9327
#define LCD_RD   A0
#define LCD_WR   A1
#define LCD_RS   A2
#define LCD_CS   A3
#define LCD_REST A4

void Lcd_Writ_Bus(char VH)
{
 unsigned char i,temp,data;
 data=VH;
 for(i=8;i<=9;i++)
 {
   temp=(data&0x01);
   if(temp)
     digitalWrite(i,HIGH);
   else
     digitalWrite(i,LOW);
   data=data>>1;
 }
 for(i=2;i<=7;i++)
 {
   temp=(data&0x01);
   if(temp)
     digitalWrite(i,HIGH);
   else
     digitalWrite(i,LOW);
   data=data>>1;
 }

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

void Lcd_Write_Com(char VH)
{
 digitalWrite(LCD_RS,LOW);
 Lcd_Writ_Bus(VH);
}

void Lcd_Write_Data(char VH)
{
 digitalWrite(LCD_RS,HIGH);
 Lcd_Writ_Bus(VH);
}

void Lcd_Write_Com_Data(int com,int dat)
{
 Lcd_Write_Com(com);
 Lcd_Write_Data(dat);
}

void Address_set(unsigned int x1,unsigned int y1,unsigned int x2,unsigned int y2)
{
 Lcd_Write_Com(0x2a); // Set_column_address 4 parameters
 Lcd_Write_Data(x1>>8);
 Lcd_Write_Data(x1);
 Lcd_Write_Data(x2>>8);
 Lcd_Write_Data(x2);

 Lcd_Write_Com(0x2b); // Set_page_address 4 parameters
 Lcd_Write_Data(y1>>8);
 Lcd_Write_Data(y1);
 Lcd_Write_Data(y2>>8);
 Lcd_Write_Data(y2);

 Lcd_Write_Com(0x2c); // Write_memory_start
}

void Lcd_Init(void)
{
 digitalWrite(LCD_REST,HIGH);
 delay(5);
 digitalWrite(LCD_REST,LOW);
 delay(15);
 digitalWrite(LCD_REST,HIGH);
 delay(15);

 digitalWrite(LCD_CS,HIGH);
 digitalWrite(LCD_WR,HIGH);
 digitalWrite(LCD_CS,LOW);  //CS

 Lcd_Write_Com(0xE9);
 Lcd_Write_Data(0x20);

 Lcd_Write_Com(0x11); //Exit Sleep
 delay(100);

 Lcd_Write_Com(0xD1);
 Lcd_Write_Data(0x00);
 Lcd_Write_Data(0x71);
 Lcd_Write_Data(0x19);

 Lcd_Write_Com(0xD0);
 Lcd_Write_Data(0x07);
 Lcd_Write_Data(0x01);
 Lcd_Write_Data(0x08);

 Lcd_Write_Com(0x36);
 Lcd_Write_Data(0x48);

 Lcd_Write_Com(0x3A);
 Lcd_Write_Data(0x05);

 Lcd_Write_Com(0xC1);
 Lcd_Write_Data(0x10);
 Lcd_Write_Data(0x10);
 Lcd_Write_Data(0x02);
 Lcd_Write_Data(0x02);

 Lcd_Write_Com(0xC0); //Set Default Gamma
 Lcd_Write_Data(0x00);
 Lcd_Write_Data(0x35);
 Lcd_Write_Data(0x00);
 Lcd_Write_Data(0x00);
 Lcd_Write_Data(0x01);
 Lcd_Write_Data(0x02);

 Lcd_Write_Com(0xC5); //Set frame rate
 Lcd_Write_Data(0x04);

 Lcd_Write_Com(0xD2); //power setting
 Lcd_Write_Data(0x01);
 Lcd_Write_Data(0x44);

 Lcd_Write_Com(0xC8); //Set Gamma
 Lcd_Write_Data(0x04);
 Lcd_Write_Data(0x67);
 Lcd_Write_Data(0x35);
 Lcd_Write_Data(0x04);
 Lcd_Write_Data(0x08);
 Lcd_Write_Data(0x06);
 Lcd_Write_Data(0x24);
 Lcd_Write_Data(0x01);
 Lcd_Write_Data(0x37);
 Lcd_Write_Data(0x40);
 Lcd_Write_Data(0x03);
 Lcd_Write_Data(0x10);
 Lcd_Write_Data(0x08);
 Lcd_Write_Data(0x80);
 Lcd_Write_Data(0x00);

 Lcd_Write_Com(0x2A);
 Lcd_Write_Data(0x00);
 Lcd_Write_Data(0x00);
 Lcd_Write_Data(0x00);
 Lcd_Write_Data(0xeF);

 Lcd_Write_Com(0x2B);
 Lcd_Write_Data(0x00);
 Lcd_Write_Data(0x00);
 Lcd_Write_Data(0x01);
 //  Lcd_Write_Data(0x3F);
 Lcd_Write_Data(0x8F); // on internet

 Lcd_Write_Com(0x29); //display on

 Lcd_Write_Com(0x2C); //display on

 digitalWrite(LCD_CS,HIGH);
}

void H_line(unsigned int x, unsigned int y, unsigned int l, unsigned int c)
{
 unsigned int i,j;
 Lcd_Write_Com(0x02c); //write_memory_start
 digitalWrite(LCD_RS,HIGH);
 digitalWrite(LCD_CS,LOW);
 l=l+x;
 Address_set(x,y,l,y);
 j=l*2;
 for(i=1;i<=j;i++)
 {
   Lcd_Write_Data(c);
 }
 digitalWrite(LCD_CS,HIGH);
}

void V_line(unsigned int x, unsigned int y, unsigned int l, unsigned int c)
{
 unsigned int i,j;
 Lcd_Write_Com(0x02c); //write_memory_start
 digitalWrite(LCD_RS,HIGH);
 digitalWrite(LCD_CS,LOW);
 l=l+y;
 Address_set(x,y,x,l);
 j=l*2;
 for(i=1;i<=j;i++)
 {
   Lcd_Write_Data(c);
 }
 digitalWrite(LCD_CS,HIGH);
}

void Rect(unsigned int x,unsigned int y,unsigned int w,unsigned int h,unsigned int c)
{
 H_line(x  , y  , w, c);
 H_line(x  , y+h, w, c);
 V_line(x  , y  , h, c);
 V_line(x+w, y  , h, c);
}

void Rectf(unsigned int x,unsigned int y,unsigned int w,unsigned int h,unsigned int c)
{
 unsigned int i;
 for(i=0;i<h;i++)
 {
   H_line(x  , y  , w, c);
   H_line(x  , y+i, w, c);
 }
}

void LCD_Clear(unsigned int j)
{
 unsigned int i,m;
 Lcd_Write_Com(0x02c); //write_memory_start
 digitalWrite(LCD_RS,HIGH);
 digitalWrite(LCD_CS,LOW);
 Address_set(0,0,479,399);

 for(i=0;i<480;i++)
   for(m=0;m<400;m++)
   {
     Lcd_Write_Data(j);
   }
 digitalWrite(LCD_CS,HIGH);
}

void setup()
{
 for(int p=2;p<10;p++)
 {
   pinMode(p,OUTPUT);
 }
 pinMode(A0,OUTPUT);
 pinMode(A1,OUTPUT);
 pinMode(A2,OUTPUT);
 pinMode(A3,OUTPUT);
 pinMode(A4,OUTPUT);
 digitalWrite(A0, HIGH);
 digitalWrite(A1, HIGH);
 digitalWrite(A2, HIGH);
 digitalWrite(A3, HIGH);
 digitalWrite(A4, HIGH);
 Lcd_Init();
 LCD_Clear(0x00);
}

void loop()
{

 for(int i=0;i<1000;i++)
 {
   Rect(random(300),random(300),random(300),random(300),random(65535)); // rectangle at x, y, with, hight, color
 }
 LCD_Clear(0x00);
}

Here are some pictures:

Any suggestions?

Please share some code as well, to help diagnose the problem.

I was able to make mine work, but these screens are all a little different, please post a link to the exact product you have. You don't have any code to read the touch input.

Please fix your images by adding them using the icon of the mountain when you are editing.  They are not valid.

Try to use MCUFriend kbv library I used this library for a 3.5 inch display and the driver on it was ILI9486 this library includes all the function and I have tested the touch also this library works good for it also

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


text:
MFRC522 board not detected. Red LED lighting
Mega 2560.
I can't get the RFID board detected. The code is as below, and outputs Didn't find MFRC522 board.. I also tested some other library and test code with success.
I triple checked the wires (3,3V pin, GND, and PWM pin 8 and 9).
I have some questions:

All tutorials shows that MOSI, MISO, SCK needs to be hooked up to digital pin 50, 51, 52. But I don't understand why these matter, because they are not referenced in any code I've found? Are they really necessary? And if so, does it have to be 50,51,52? Can't it be any other digital pin?

I accidentally connected it to 5V at first, for maybe 1 minute. Could it be burnt? The LED still lights RED when connected with power.

If the problem was the (correct) library was not loaded, wouldn't I get a compile error?

I'm running this code:
    #include <MFRC522.h>
    #include <SPI.h>

    #define SAD 9
    #define RST 8

    MFRC522 nfc(SAD, RST);

    void setup() {
      SPI.begin();
      Serial.begin(115200);

      Serial.println("Looking for MFRC522.");
      nfc.begin();

      uint8_t version = nfc.getFirmwareVersion();
      if (! version) {
        Serial.print("Didn't find MFRC522 board.");
        while(1); //halt
      }

      Serial.print("Found chip MFRC522 ");
      Serial.print("Firmware ver. 0x");
      Serial.print(version, HEX);
      Serial.println(".");

      if (nfc.digitalSelfTestPass()) {
          Serial.print("Digital self test by MFRC522 passed.");
      } else {
          Serial.print("Digital self test by MFRC522 failed.");
      }
    }

    void loop() {

    }

I almost tried to answer to this with one giant answer despite that you're really asking about three thing that you know of and in away more things than that.  But then I saw "I also tested some other library and test code with success" What kind of success are we walking about here and did you have that success before or after hooking 5V to the board?  Because if "success" was that you got it reading you should say whether or not you managed to do that after feeding it 5V.  That said, it would be better to pick one question and go with that.

Welcome, hopefully we can help you. You do not have to connect MOSI, MISO, SCK, CS if you do not want to however without them connected properly it will not work. Note you did not mention the CS pin, that is also needed as that is what tells the MFRC522 it has been selected. Those pins are what is used to communicate with the device. The pins may be different for different boards but you need to check the data sheet for that. The numbers appear correct for the Mega.
The LED tells you that there is power there, it in no way tells you if the board is good. Did you fry it, probably probably as the MFRC522 is a 3V3 device but that is not a given as I do not know what pin you connected the 5V to. More than a few nanoseconds on a voltage higher than rated tends to fry things, but you could be lucky I have no way of knowing. The Mega is 5V so that would probably be OK.
You ask: "If the problem was the (correct) library was not loaded, wouldn't I get a compile error?", again no not necessarily. The compiler does not know your design or what you are connecting to. If the library happens to have functions etc appropriately named it will compile with errors but the odds are very slim your code will work.


text:
Arduino sketch doesn't work when uploaded to arduino nano and OLED display shows npothing (possible issue: lack of memory)
I need some hand here. I wrote some code for a small arduino console-like device that has five pushbuttons, 128x64 I2C OLED display and arduino nano. And it doesn't work when uploaded to arduino nano - display goes blank.
Anamnesis: The Code includes two classes: menu class and button class. When I upload the code on my device - it doesn’t display anything on oled but arduino still executes the code. Wiring is not an issue. But when I remove games_menu or pongLevel_menu or settings_menu and sound_menu from class objects and comment lines where these objects are used, the code works just fine.
Question: Maybe the thing is that arduino nano has some kind of memory, where it stores class objects, and my code uses too much of this memory. Since I am kinda new to arduino and programming - I can make mistakes. Can you please help me with this problem? Minimum reproducible code (sorry, I know that it looks like a big chunk of code but that's what I can shrink it to so that it still reproduces the problem):
#include "Wire.h"
#include "Adafruit_GFX.h"
#include "Adafruit_SSD1306.h"
Adafruit_SSD1306 display(128, 64, &Wire, -1);
//------------variables-------------
    //--------menu variables--------
    unsigned long sec;
    byte selY = 12;
    boolean up;
    boolean down;
    boolean left;
    boolean right;
    boolean a;
    boolean b;
    int location = 0;

    //--------stopwatch variables--------
    unsigned long startTime;
    bool stTimeB = 1;
    unsigned long millisec;
    byte seconds;
    byte minutes;
    byte hours;
//--------classes-------
    //----class menu----
    class menu {
    public:
      menu(String caption, String item1, String item2, String item3, String item4, unsigned int minn, unsigned int maxx);
      void play();

    private:
     String cap;
     String it1;
     String it2;
     String it3;
     String it4;
     unsigned int _min;
     unsigned int _max;
  };
  menu::menu(String caption, String item1, String item2, String item3, String item4, unsigned int minn, unsigned int maxx){
    cap = caption;
    it1 = item1;
    it2 = item2;
    it3 = item3;
    it4 = item4;
    _min = minn;
    _max = maxx;

    }

  void menu::play(){
    if(up == 1 && millis() - sec > 199){
      selY -= 10;
      sec = millis();
    }
    if(down == 1 && millis() - sec > 199){
      selY += 10;
      sec = millis();
    }
    if(selY < _min){
      selY = _max;
    }
    if(selY > _max){
      selY = _min;
    }

    display.clearDisplay();
    display.setTextSize(1);
    display.setTextColor(WHITE);
    display.setCursor(50, 0);
    display.print(cap);
    display.drawLine(0, 9, 128, 9, WHITE);
    display.setCursor(6, 13);
    display.print(it1);
    display.setCursor(6, 23);
    display.print(it2);
    display.setCursor(6, 33);
    display.print(it3);
    display.setCursor(6, 43);
    display.print(it4);
    display.drawRoundRect(1, selY, 122, 11, 4, WHITE);
    display.display();

  }
    //--------class button--------
    class button {
  public:
    button(byte xx, byte yy, byte rr, byte var, String caption11, String caption22, String type_, byte tSize);
    void disp();
    void changeCap(bool caption);
    bool getStatus();
    void update_();

  private:
   byte x;
   byte y;
   byte r;
   byte txtSize;
   bool capB = 0; // 1
   bool pres = 0;
   byte btnPin;
   String caption1;
   String caption2;
   String type;
};
button::button(byte xx, byte yy, byte rr, byte var, String caption11, String caption22, String type_, byte tSize){
  x = xx;
  y = yy;
  r = rr;
  btnPin = var;
  caption1 = caption11;
  caption2 = caption22;
  type = type_;
  txtSize = tSize;
  }

void button::disp(){
  display.setTextSize(txtSize);
  if(pres == 0){
    display.drawRoundRect(x, y, (((caption1.length() + 2)*(5*txtSize)) + (caption1.length() - 1)), ((7+4)*txtSize), r, WHITE);
    display.setTextColor(WHITE);
  }
  else{
    display.fillRoundRect(x, y, (((caption2.length() + 2)*(5*txtSize)) + (caption2.length() - 1)), ((7+4)*txtSize), r, WHITE);
    display.setTextColor(BLACK);
  }

  if(pres == 0){display.setTextColor(WHITE); }
  if(pres == 1){display.setTextColor(BLACK);}

  if(capB == 0){
    if(pres == 1){display.setTextColor(BLACK);}
    if(pres == 0){display.setTextColor(WHITE);}
    display.setCursor(x+(5*txtSize), y+(2*txtSize));
    display.print(caption1);
  }
  else{
    display.setCursor(x+(5*txtSize), y+(2*txtSize));
    display.print(caption2);
  }
}

bool button::getStatus(){
  return pres;
}
void button::update_(){
  if(type == "push_button"){
    if(!digitalRead(btnPin) == 1 && millis() - sec > 19){
      pres = 1;
      sec = millis();
    }
    if(!digitalRead(btnPin) == 0){
      pres = 0;
    }
  }
  if(type == "switch"){
    if(!digitalRead(btnPin) == 1 && millis() - sec > 189){
      pres = !pres;
      sec = millis();
    }
  }
}

void button::changeCap(bool captionB){
  capB = captionB;
}
//--------class objects--------
menu main_menu("main", "games", "stopwatch", "timer...", "settings", 12, 42);
    menu games_menu("games", "pong", "guess a number...", " ", " ", 12, 22);
      menu pongLevel_menu("level", "easy", "hard", "expert", "impossible ", 12, 42);
    menu settings_menu("settings", "sound", "credits", " ", " ", 12, 22);
        menu sound_menu("sound", "on", "off", " ", " ", 12, 22);

button startB(25, 32, 6, 14, "start", "stop", "switch", 2);

//--------functions-----------
void buttonsUpdate(){
  up = !digitalRead(A0);
  down = !digitalRead(A2);
  left = !digitalRead(12);
  right = !digitalRead(A1);
  a = !digitalRead(4);
}
void resetTime(){
    millisec = 0;
    seconds = 0;
    minutes = 0;
    hours = 0;
}
void cookTime(){ // logic for stopwatch and calcuulating milliseconds, seconds, minutes and hours
  startB.update_();
  if(startB.getStatus() == 1){startB.changeCap(1);digitalWrite(13,1);}
  if(startB.getStatus() == 0){startB.changeCap(0);stTimeB = 1;digitalWrite(13,0);}

  if(startB.getStatus() == 1){
    if(stTimeB == 1){resetTime(); startTime = millis(); stTimeB = 0; }
    millisec = ((millis()-startTime)/10) % 100;
    seconds = ((millis()-startTime)/1000)%60;
    minutes = ((millis()-startTime)/(1000*60))%60;
    hours = ((millis()-startTime)/(1000*60*60))%60;
  }
}

void dispStopwatch(){ // display stopwatch
  cookTime();
  display.clearDisplay();
  startB.disp();
  display.setTextColor(WHITE);
  display.setTextSize(2);
  display.setCursor(8, 10);
  display.print(hours);
  display.print("|");
  display.print(minutes);
  display.print("|");
  display.print(seconds);
  display.print("|");
  display.print(millisec);
  display.display();
}

void setup() {
  Wire.begin();
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
  display.clearDisplay();
  pinMode(13, OUTPUT);
  // buttons' pins setup
  pinMode(A0, INPUT_PULLUP); // up
  pinMode(A1, INPUT_PULLUP); // right
  pinMode(12, INPUT_PULLUP); // left
  pinMode(A2, INPUT_PULLUP); // down

  pinMode(4, INPUT_PULLUP);  // a
 }

void loop() {
 buttonsUpdate();
  if(up == 1 && down == 1){location = 0;}

  if(location == 0){//main menu
    main_menu.play();
    if(a == 1 && selY == 12/*if a btn is clicked while selected first item*/ && millis() - sec > 199){location = 1/*games*/; sec = millis();}
    if(a == 1 && selY == 22/*if a btn is clicked while selected first second*/ && millis() - sec > 199){location = 2/*stopwatch*/; sec = millis();}
    //if(a == 1 && selY == 32 && millis() - sec > 199){location = 3/*timer*/; sec = millis();}
    if(a == 1 && selY == 42/*if a btn is clicked while selected first fourth*/ && millis() - sec > 199){location = 4/*settings*/; sec = millis();}
  }

  if(location == 1){//game menu
        games_menu.play();
        if(a == 1 && selY == 12 && millis() - sec > 199){location = 11/*pong*/; sec = millis();}
      }
          if(location == 11){//pong levels
          pongLevel_menu.play();
          }

  if(location == 2){//stopwatch
        dispStopwatch();
  }
  if(location == 4){//settings
        settings_menu.play();
        if(a == 1 && selY == 12 && millis() - sec > 199){location = 41/*sound*/; sec = millis();}
        if(a == 1 && selY == 22 && millis() - sec > 199){location = 42/*credits*/; sec = millis();}
      }
          if(location == 41){// sound menu
            sound_menu.play();
          }
          if(location == 42){// credits
           // drawBitmap();
          }
}

Please put your code into the question. Also what is that link? To a comment on SE with another link to a different question on SE?

I tried to put code but it separates some lines and writes it as text. Link is to stack Overflow where code can pase normaly

Responders on StackOverflow have already suggested you make use of Flash memory to reduce the amount of the (very limited) RAM your code needs. Some additional suggestions: Strings often fragment available RAM into unusably small pieces; C strings - null-terminated character arrays - are much more RAM-friendly. Any constants, constant strings, constant members of objects, can be moved to Flash too, to free more of the limited RAM. Search "PROGMEM Arduino" for tutorials. Practice with them until you can apply the principles to your code.

Thank you very much for this suggestion, I will try to implement that into my code

Link is to stack Overflow where code can pase normaly ... the code parses the same way here ... read Syntax highlighting for code here
https://arduino.stackexchange.com/editing-help ...

I have copied the code.  But please delete the question on stackoverflow.  Multi-postings is frowned upon.


text:
How to produce a USB CDC serial port for Arduino nano 33 BLE?
I'm trying to program an Arduino Nano 33 BLE bare-metal to get some precise timing and size measurements. I've managed to upload the code to my card, but I cannot communicate with it. More specifically, when I upload the code, the port 'deactivates' after I upload the code, so the serial monitor prints a cannot exec '/dev/ttyACM0' error.
Can someone help me figure out how to make it work? I've seen tutorials online but they're for AVR microcontrollers, and I've been told that this specific board isn't. I've also been told that I must include some code in my c/cpp file to produce a USB CDC serial port, but I don't know how to do that.

upload a simple example from the IDE Examples menu Communication section

What are you measuring that you can't do it with freeRTOS/mbed-os? You can always use timer(s), events and tasks + shortcuts (or generic connection) and DMA

Well, it seems that mbedOS is messing up with my timing experiments, the measurements fluctuate when they shouldn't. Plus, even an empty sketch uses a lot of memory, and I wish to be able to compare the memory consumption of multiple programs. I guess I could always subtract the cost of an empty sketch, but that doesn't seem very practical to do that by hand.

I'm not sure, but I think rtos usually has some memory stats https://os.mbed.com/docs/mbed-os/v6.16/apis/runtime-memory-statistics.html about timing, you can use high prio task (+ delays to allow lower priority tasks to do run)

Have you seen any of these Q+As? https://arduino.stackexchange.com/search?q=%2Fdev%2FttyACM0

The Nano 33 BLE board uses a NORDIC nRF52840 processor which contains the USB interface hardware inside the processor. The current Arduino Uno uses an Atmel (now owned by Microchip) processor and uses an external processor for USB communications. So any Arduino USB tutorial will be very different with respect to these two Arduino designs.
Normally, Arduino Sketches (Programs) are only part of all the software running on a processor. The preprogrammed software on a new Arduino board abstracts the more complex part of embedded programming from the average Arduino user. This likely includes a working USB port.
To do bare metal programming on a NORDIC nRF52840 processor, consider starting with the NORDIC Software Development Kit (SDK). Also, most vendors support their own development boards (provide example programs and libraries) better then development boards made else where.  Consider this before committing to learning how to bring up a "bear metal" USB/CDC peripheral device using the Nano 33 BLE board.
An alternative approach: Many ports of Arduino occur on github.com.  The adaptation of the Arduino code may offer insights as to how the host processor's hardware works. The Nano 33 BLE preprogrammed software comes from this github repository.

the current core for Nano BLE is here https://github.com/arduino/ArduinoCore-mbed

Thanks, fixed the answer to include the new link.


text:
Do we need to burn bootloader in new Atmega328p before uploading the arduino code
I have an arduino code which is working fine. Now I am planning to make a PCB out of it. But I do not want to use the complete Arduino board. I just want to use the Atmega328p microcontroller. So my plan is to connect the USBasp programmer to the new Atmega328p and upload the code. So before this code, do I need to upload the bootloader or uploading the code first will run fine.

You just need to set the fuses. You can do that using the command line, and the avrdude application. avrdude is somewhere inside the Arduino application folder. You'd run something like avrdude -v -patmega328 -cusbasp -B10 -Pusb -U lfuse:w:0xA4:m -U hfuse:w:0xD1:m  (those fuse values are most likely not the correct ones). Note the -B 10, is to slow down the USBasp programmer, as by default the ATMega328 runs at 1Mhz.

Tools > Burn Bootloader in the Arduino IDE does two things:

Set fuses according to the settings in boards.txt for the Tools > Board selection
Install the bootloader.

The latter is pointless since when you do an Upload Using Programmer the bootloader will be overwritten but the former is very important to do the first time you use a new chip(or anytime you want to change the fuses) to be sure that the correct fuses are set, which likely will be different from the default settings of the chip when you get it. Upload Using Programmer does not set fuses, the only way to do this via the Arduino IDE is Tools > Burn Bootloader.
So yes, you should Burn Bootloader.

The act of burning the bootloader doesn't burn the fuses. They are actually a completely separate command that is executed in sequence with burning the bootloader. You do not need to burn the bootloader to set the fuses, you can do them separately. Burning the bootloader is an "easy" way of doing it, however you should really learn how to control the fuses properly if you are going to work with bare chips.

The only thing the bootloader for the ATmega328P does is to enable UART programming. If you are only using ISP then there is no need to have the bootloader.

Okay. I will try it and will let you know.

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


text:
expected ')' before executarAcao
here is the code:
#define pinSom 7
#define pinRele1 2
#define pinRele2 3
#define tempoMaximoDeUmaPalma 150 //milisegundos
#define tempoMaximoEntrePalmas 500 //milisegundos

int contaPalmas = 0;
long tempoEspera = 0;
long tempoEsperaEntrePalmas = 0;

void setup() {
  // put your setup code here, to run once:
    pinMode(pinSom, INPUT);
    pinMode(pinRele1, OUTPUT);
    pinMode(pinRele2, OUTPUT);
}

void loop() {{
  // verifica o estado do sensor de som (ele fica normalmente com
  int sensorSom = digitalRead(pinSom) ;

  //se o sensor detectou palmas
  if (tempoEspera == LOW) {

      //espera um tempo para não detectar a mesma palma mais de uma vez
    tempoEspera = tempoEsperaEntrePalmas = millis();
    contaPalmas++;
  }else if ((millis() - tempoEspera) >= tempoMaximoDeUmaPalma)
     tempoEspera = 0;
  }

    //caso exceda o tempo maximo entre palmas, zera o contador de palmas

    {

    if ( (contaPalmas != 0) && ((millis() - tempoEsperaEntrePalmas)
    (i get the error here) executarAcao();
    contaPalmas = 0;
    TempoEsperaEntrePalmas = millis();

 }
}
void executarAcao()
{
   switch (contaPalmas) {
    case 2:
      digitalWrite(pinRele1, !digitalRead(pinRele1));
      break;
   }

Your brackets are a mess.

Welcome to Arduino SE!! , I think you add more brackets on void loop() {{ line , please check again your code!!!

on SO such questions are closed as "typo error", because they are not worth an answer. answers are downvoted.

You're missing closing brackets in the line above your error.
It compiles now, but I have no idea whether it works as you intend.
Try forcing yourself to always open and close brackets when you begin one, and making sure to indent properly.
Also, Arduino code is case-sensitive.
#define pinSom 7
#define pinRele1 2
#define pinRele2 3
#define tempoMaximoDeUmaPalma 150 //milisegundos
#define tempoMaximoEntrePalmas 500 //milisegundos

int contaPalmas = 0;
long tempoEspera = 0;
long tempoEsperaEntrePalmas = 0;

void executarAcao()
{
  switch (contaPalmas) {
    case 2:
      digitalWrite(pinRele1, !digitalRead(pinRele1));
      break;
  }
}

void setup() {
  // put your setup code here, to run once:
  pinMode(pinSom, INPUT);
  pinMode(pinRele1, OUTPUT);
  pinMode(pinRele2, OUTPUT);
}

void loop() {
  // verifica o estado do sensor de som (ele fica normalmente com
  int sensorSom = digitalRead(pinSom);

  //se o sensor detectou palmas
  if (tempoEspera == LOW) {
      //espera um tempo para não detectar a mesma palma mais de uma vez
    tempoEspera = tempoEsperaEntrePalmas = millis();
    contaPalmas++;
  }
  else if ((millis() - tempoEspera) >= tempoMaximoDeUmaPalma) {
     tempoEspera = 0;
  }
    //caso exceda o tempo maximo entre palmas, zera o contador de palmas
  else {
    if ((contaPalmas != 0) && (millis() - tempoEsperaEntrePalmas)) {
      executarAcao();
      contaPalmas = 0;
      tempoEsperaEntrePalmas = millis();
    }
  }
}

This error means you did not close a pair of brackets, either {} or ().  The solution is to check through your code to make sure brackets are always in pairs.


text:
ADXL345 I2C setup not returning anything
My hookup is like this:
GND - GND  VCC - 5V  CS - 5V  SDO - GND  SDA - A4  SCL - A5
Here is the code:
#include <Wire.h>
#include <ADXL345.h>

ADXL345 accelerometer;

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

  // Initialize ADXL345
  Serial.println("Initialize ADXL345");

  if (!accelerometer.begin())
  {
    Serial.println("Could not find a valid ADXL345 sensor, check wiring!");
    delay(500);
  }
  if (accelerometer.begin())
  {

  // Values for Free Fall detection
  accelerometer.setFreeFallThreshold(0.35); // Recommended 0.3 - 0.6 g
  accelerometer.setFreeFallDuration(0.1);  // Recommended 0.1 s

  // Select INT 1 for get activities
  accelerometer.useInterrupt(ADXL345_INT1);

  // Check settings
  checkSetup();
  }
}

void checkSetup()
{
  Serial.print("Free Fall Threshold = "); Serial.println(accelerometer.getFreeFallThreshold());
  Serial.print("Free Fall Duration = "); Serial.println(accelerometer.getFreeFallDuration());
}

void loop(void)
{
  delay(50);

  // Read values for activities
  Vector norm = accelerometer.readNormalize();

  // Read activities
  Activites activ = accelerometer.readActivites();

  if (activ.isFreeFall)
  {
    Serial.println("Free Fall Detected!");
  }
}

It comes from this Github link: https://github.com/jarzebski/Arduino-ADXL345/blob/master/ADXL345_free_fall/ADXL345_free_fall.ino
Initially, it would return "Could not find a valid ADXL345 sensor, check wiring!" in serial monitor. After messing with some wiring and changing to SPI
and back to I2C, it only returns "Initialize ADXL345".
I've added the second if() statement because it wouldn't say anything other than "Initialize ADXL345" even with the first if() statement, or with the first if() followed by an else. It should print the Free Fall Threshold and Duration but it hasn't. I have to leave and won't be back until tomorrow, so when I get back I'll try removing the checkSetup() command and maybe put something else in it's place to verify it's working. I feel like the answer is staring me in the face.
EDIT: Okay so after I finally got up from my computer for once, a thought popped into my mind and I figured the reason why checkSetup() isn't returning either string is because it's declared after setup() calls checkSetup()? Am I right? I feel like this would be the case in other languages.

Provide a link to the specific module you have; are you sure that I2C pullups are built-in? What did you change in the wiring? You're calling begin() twice; if you want to test the return value, call it once and store the result in a variable which you can then test as often as you wish. Also try using a more popular library like Adafruit's.

Here is the link to the Sparkfun ADXL345 I have: https://www.sparkfun.com/products/9836
I've gone ahead and changed from 5v to 3.3v, have a small wire that just leads from VCC to CS, and have 2 220 ohm resistors going from 3.3v on my breadboard to SDA and SCL which have wires that go into pins A4 and A5 on my microcontroller, respectively. The microcontroller is a Sparkfun Redboard, which is the same as an Arduino Uno it seems. I've removed the second begin(), and now it will say "ADXL345 Initialize" followed by "Free fall Threshold = " but no value and that's it.

You may have damaged the chip with 5 V already. Sparkfun didn't include a regulator in their breakout. Your pull-ups are also too small; significant current flows when the I2C lines are pulled low. Use two 4.7k or 10k resistors instead. Assuming your Redboard is just like the Uno, connect pin 2 to the INT1 pin of the breakout, to make use of the interrupt capabilities. You also need to call attachInterrupt() and register a handler.
However, you bought this module from Sparkfun, as well as your Redboard. You should first follow their tutorial and library before trying any others. Theirs is SPI-based though. If you must use I2C, try out the Adafruit library.


text:
Different ways (and the fastest) to compute sines (and cosines) in Arduino
I am using an Arduino Uno board to compute the angles of my system (robotic arm). The angles are actually 10 bit values (0 to 1023) from the ADC, using the full range of the ADC. I am only going to be operating in the 1st quadrant (0 to 90 deg), where both sines and cosines are positive, so there is no problem with negative numbers. My doubts can be expressed in 3 questions:

What are the different ways to compute these trigonometric functions on Arduino?
What is the fastest way to do the same?
There are the sin() and cos() functions in the Arduino IDE, but how does the Arduino actually calculate them (as in do they use look-up tables, or approximations etc.)? They seem like an obvious solution, but I would like to know their actual implementation before I try them out.

PS: I am open to both standard coding on the Arduino IDE and assembly coding, as well as any other options not mentioned. Also I have no problems with errors and approximations, which are inevitable for a digital system; however if possible it would be good to mention the extent of possible errors

Would you be ok with approximate values?

Yes actually, but I would like to know the extent of the error of different methods. This is not a precision product but a side project of mine. Actually approximations are inevitable for almost any (if not any) digital system implementing a mathematical function

I assume you are wanting to work in degrees. Are you going to want to input integers or decimal numbers for the angle?

Degrees yes. I think it would be easier to write code and test if we use integers, so I would go with that. I ll put more clear information about edits

For just 90 (integer) degrees a 90-entry lookup table would be fastest and most efficient. In fact for the full 360 degrees you can use a 90-entry lookup table. Just read it backwards for 90-179 and invert it for 180-269. Do both for 270-359.

Could you quantify your accuracy requirement? The approximation cos(π/2x) ≈ 1−x² has a maximal error of 5.6e-2. And (1−x²)(1−0.224x²), which costs 3 multiplications, is good to within 9.20e-4.

@EdgarBonet Sorry for the late reply. I dont have any current quantified fixed accuracy. I just want to know all possible options for now

The two basic methods are mathematical calculation (with polynomials) and lookup tables.
The Arduino's math library (libm, part of avr-libc) uses the former. It is optimised for the AVR in that it is written with 100% assembly language, and as such is almost impossible to follow what it's doing (there's zero comments as well). Rest assured though it will be the most optimised pure-float implementation brains far superior to ours could come up with.
However the key there is float. Anything on the Arduino involving floating point is going to be heavyweight by comparison to pure integer, and since you are only requesting integers between 0 and 90 degrees a simple lookup table is by far the simplest and most efficient method.
A table of 91 values will give you everything from 0 to 90 inclusive. However if you make that a table of floating point values between 0.0 and 1.0 you still then have the inefficiency of working with floats (granted not as inefficient as calculating sin with floats), so storing a fixed point value instead would be far more efficient.
That may be as simple as storing the value multiplied by 1000, so you have between 0 and 1000 instead of between 0.0 and 1.0 (for instance sin(30) would be stored as 500 instead of 0.5). More efficient would be to store the values as, for instance, a Q16 value where each value (bit) represents 1/65536th of 1.0. These Q16 values (and the related Q15, Q1.15, etc) are more efficient to work with since you have powers-of-two which computers love to work with instead of powers-of-ten which they hate working with.
Don't forget as well that the sin() function expects radians, so you first have to convert your integer degrees into a floating point radians value, making the use of sin() even more inefficient compared to a lookup table that can work directly with the integer degrees value.
A combination of the two scenarios, though, is possible. Linear interpolation will allow you to get an approximation of a floating point angle between two integers. It's as simple as working out how far between two points in the lookup table you are and creating a weighted average based on that distance of the two values. For instance if you are at 23.6 degrees you take (sintable[23] * (1-0.6)) + (sintable[24] * 0.6). Basically your sine wave becomes a series of discrete points joined together by straight lines.  You trade accuracy for speed.

I wrote a library a while back that used a Taylor polynomial for sin/cos that was faster than the library. Given, I was using floating point radians as the input for both.

There are some good answers here but I wanted to add a method which hasn't been mentioned yet, one very well suited to computing trigonometric functions on embedded systems, and that's the CORDIC technique
Wiki Entry Here It can compute trig functions using only shifts and adds and a small look-up table.
Here's a crude example in C. In effect, it implements the C libraries' atan2() function using CORDIC (i.e. find an angle given two orthogonal components.) It uses floating point, but can be adapted for use with fixed-point arithmetic.
/*
 * Simple example of using the CORDIC algorithm.
 */

#include <stdio.h>
#include <math.h>

#define CORDIC_TABLE_SIZE  16

double cordic_table[CORDIC_TABLE_SIZE];

void init_table(void);
double angle(double I, double Q);

/*
 * Given a sine and cosine component of an
 * angle, compute the angle using the CORIDC
 * algoritm.
 */
double angle(double I, double Q)
{
    int L;
    double K = 1;
    double angle_acc = 0;
    double tmp_I;

    if (I < 0) {
        /* rotate by an initial +/- 90 degrees */
        tmp_I = I;
        if (Q > 0.0) {
            I = Q;           /* subtract 90 degrees */
            Q = -tmp_I;
            angle_acc = -90;
        } else {
            I = -Q;          /* add 90 degrees */
            Q = tmp_I;
            angle_acc = 90;
        }
    } else {
        angle_acc = 0;
    }

    /* rotate using "1 + jK" factors */
    for (L = 0, K = 1; L <= CORDIC_TABLE_SIZE; L++) {
        tmp_I = I;
        if (Q >= 0.0) {
            /* angle is positive: do negative roation */
            I += Q * K;
            Q -= tmp_I * K;
            angle_acc -= cordic_table[L];
        } else {
            /* angle is negative: do positive rotation */
            I -= Q * K;
            Q += tmp_I * K;
            angle_acc += cordic_table[L];
        }
        K /= 2.0;
    }
    return -angle_acc;
}

void init_table(void)
{
    int i;
    double K = 1;

    for (i = 0; i < CORDIC_TABLE_SIZE; i++) {
        cordic_table[i] = 180 * atan(K) / M_PI;
        K /= 2.0;
    }
}
int main(int argc, char **argv)
{
    double I, Q, A, Ar, R, Ac;

    init_table();

    printf("# Angle,    CORDIC Angle,  Error\n");
    for (A = 0; A < 90.0; A += 0.5) {

        Ar = A * M_PI / 180; /* convert to radians for C's sin & cos fn's */

        R = 5;  // Arbitrary radius

        I = R * cos(Ar);
        Q = R * sin(Ar);

        Ac = angle(I, Q);
        printf("%9f, %9f,   %12.4e\n", A, Ac, Ac-A);
    }
    return 0;
}

But try the native Arduino trig functions first - they might be fast enough anyway.

I have taken a similar approach in the past, on stm8. it takes two steps: 1) calculate sin(x) and cos(x) from sin(2x), and then 2) calculate sin(x +/- x/2) from sin(x), sin(x/2), cos(x), and cos(x/2) -> through iteration you can approach your target. in  my case, i started with 45 degrees (0.707), and worked my way out to the target. it is considerably slower than the standard IAR sin() function.

I have been playing a bit with computing sines and cosines on the
Arduino using fixed-point polynomial approximations. Here are my
measurements of average execution time and worst case error, compared
with the standard cos() and sin() from avr-libc:
function    max error   cycles   time
-----------------------------------------
cos_fix()   9.53e-5     108.25    6.77 µs
sin_fix()   9.53e-5     110.25    6.89 µs
cos()       2.98e-8     1720.8   107.5 µs
sin()       2.98e-8     1725.1   107.8 µs

It's based on a 6th degree polynomial computed with only
4 multiplications. The multiplications themselves are done in
assembly, as I found that gcc implemented them inefficiently. The angles
are expressed as uint16_t in units of 1/65536 of a revolution, which
makes the arithmetic of angles naturally work modulo one revolution.
If you think this can suit your bill, here is the code: Fixed-point
trigonometry.
Sorry, I still did not translate this page, which is in French, but you
can understand the equations, and the code (variable names, comments...)
is in English.

Edit: Since the server seems to have vanished, here is some info on
the approximations I found.
I wanted to write angles in binary fixed-point, in units of quadrants
(or, equivalently, in turns). And I also wanted to use an even
polynomial, as these are more efficient to compute than arbitrary
polynomials. In other words, I wanted a polynomial P() such that
cos(π/2 x) ≈ P(x2)  for x ∈ [0,1]
I also required the approximation to be exact at both ends of the
interval, to ensure that cos(0) = 1 and
cos(π/2) = 0. These constraints led to the form
P(u) = (1 − u)(1 + uQ(u))
where Q() is an arbitrary polynomial.
Next, I searched for the best solution as a function of the degree of
Q() and found this:
        Q(u)             │ degree of P(x²) │ max error
─────────────────────────┼─────────────────┼──────────
          0              │         2       │  5.60e-2
       −0.224            │         4       │  9.20e-4
−0.2335216 + 0.0190963 u │         6       │  9.20e-6

The choice among the solutions above is a speed/accuracy trade-off. The
third solution gives more accuracy than achievable with 16-bits, and
it's the one I chose for the 16-bit implementation.

That is amazing, @Edgar.

What did you do to find the polynomial?

@TLW: I required it to have some “nice” properties (e.g. cos(0)=1), which constrained to the form (1−x²)(1+x²Q(x²)), where Q(u) is an arbitrary polynomial (it's explained in the page). I took a first-degree Q (only 2 coefficients), found the approximate coefficients by fit, then hand-tuned the optimization by trial and error.

@EdgarBonet - interesting. Note that that page does not load for me, though cached works. Could you please add the polynomial used to this answer?

@TLW: added that to the answer.

The fourth-degree solution replicates devmaster user "Nick"'s solution, though he was working with sine and got 0.225: https://stackoverflow.com/a/66868438/3770260

You could create a couple of functions that uses linear approximation to determine the sin() and cos() of a particular angle.
I am thinking something like this:

For each I have broken the graphical representation of sin() and cos() into 3 sections and have done a linear approximation of that section.
Your function would ideally first check that the range of the angel is between 0 and 90.
Then it would use an ifelse statement to determine what of the 3 sections it belongs and then does the corresponding linear calculation (ie output = mX + c)

Will not this involve floating point multiplication?

Not necessarily. You could have it so the output is scaled between 0-100 instead of 0-1. This way you are dealing with integers, not floating point. Note: 100 was arbitrary. There is no reason that you couldn't scale the output between 0-128 or 0-512 or 0-1000 or 0-1024. By using a multiple of 2, you only need to do right shifts to scale the result back down.

Pretty clever, @sa_leinad.  Upvote.  I remember doing this when working with biasing of transistors.

I looked for other people that had approximated cos() and sin() and I came across this answer:
dtb's answer to "Fast Sin/Cos using a pre computed translation array"
Basically he computed that the math.sin() function from the math library was faster than using a look-up table of values. But from what I can tell, this was computed on a PC.
Arduino has a math library included that can calculate sin() and cos().

PCs have FPUs built into them that make it fast. Arduino's don't, and that makes it slow.

The answer is also for C# which does stuff like array bounds checking.

A lookup table will be the fastest way to find sines. And if you're comfortable computing with fixed-point numbers (integers whose binary-point is somewhere other than to the right of bit-0), your further calculations with the sines will be much faster as well. That table can then be a table of words, possibly in Flash to save RAM space. Note that in your math you may need to use longs for large intermediate results.

Just for the fun of it, and to prove it can be done, I finished an AVR assembly routine to calculate sin(x) results in 24 bits (3 bytes) with one bit of error.  The input angle is in degrees with one decimal digit, from 000 to 900 (0~90.0) for the first quadrant only.  It uses less than 210 AVR instructions and runs on average of 212 microseconds, varying from 211us (angle=001) to 213us (angle=899).
It took several days to do it all, more than 10 days (free hours) just thinking about the best algorithm for the calculation, considering the AVR microcontroller, no floating point, eliminating all possible divisions. What took more time was to make the right step-up values for integers, to have good precision it needs to step-up values of 1e-8 to binary integers 2^28 or more.  Once all the errors culprits of precision and rounding up were found, increased their calculation resolution by extra 2^8 or 2^16, the best results were met.  I first simulated all the calculations on Excel taking care of having all values as Int(x) or Round(x,0) to represent exactly the AVR core processing.
For example, in the algorithm the angle must be in Radians, the input is in Degrees to facilitate for the user.  To convert Degrees to Radians the trivial formula is rad=degrees*PI/180, it seems nice and easy, but it is not, PI is an infinite number - if using few digits it will create errors at the output, division by 180 requires AVR bit manipulation since it has no division instruction, and more than that, the result would require floating point since involves numbers far below integer 1. For example, Radian of 1° (degree) is 0.017453293. Since PI and 180 are constants, why not reverse this thing for simple multiplication?  PI/180 = 0.017453293, multiply it by 2^32 and it results as a constant 74961320 (0x0477D1A8), multiply this number by your angle in degrees, lets say 900 for 90° and shift it 4 bits right (÷16) to obtain 4216574250 (0xFB53D12A), that is the radians of the 90° with 2^28 expansion, fit in 4 bytes, without a single division (except the 4 bit shift right). In a way, the error included in such trick is smaller than 2^-27.
So, all further calculations need to remember it is 2^28 higher and taken care of it. You need to divide the on-the-go results by 16, 256 or even 65536 just to avoid it use unnecessary growing hunger bytes that would not help resolution.  That was a painstaking job, just finding the minimum quantity of bits in each calculation results, keeping the results precision around 24 bits. Each one of the several calculations where done in try/error with higher or lower bits count in the Excel flow, watching the overall quantity of error bits at the result in a graph showing 0-90° with a macro running the code 900 times, once per tenth of a degree. That "visual" Excel approach was a tool I created, helped a lot to find the best solution for every single part of the code.
For example, rounding up this particular calculation result 13248737.51 to 13248738 or just lose the "0.51" decimals, how much it will affect the final result precision for all the 900 input angles (00.1 ~ 90.0) tests?
I was able to keep the animal contained within 32 bits (4 bytes) on every calculation, and ended up with the magic to obtain precision within 23 bits of the result. When checking the whole 3 bytes of the result, the error is ±1 LSB, outstanding.
The user may grab one, two or three bytes from the result for its own requirements of precision.  Of course, if just one byte is enough I would recommend to use a single 256 bytes sin table and use AVR 'LPM' instruction to grab it.
Once I had the Excel sequence running smooth and neat, the final translation from Excel to AVR assembly took less than 2 hours, as usual you should think more first, work less later.
At that time I was able to squeeze yet more and reduce registers usage. The actual (not final) code uses around 205 instructions (~410 bytes), runs a sin(x) calculation in average of 212us, clock at 16MHz. At that speed it can calculate 4700+ sin(x) per second. Not being important, but it can run a precise sinewave up to 4700Hz with 23 bits of precision and resolution, without any lookup tables.
The base algorithm is based on Taylor series for sin(x), but modified a lot to fit my intentions with the AVR microcontroller and precision in mind.
Even that using a 2700 bytes table (900 entries * 3 bytes) would be speed attractive, what is the fun or learning experience on that?  Of course, CORDIC approach was also considered, maybe later, the point here is to squeeze Taylor into the AVR core and take water from a dry rock.
I wonder if Arduino "sin(78.9°)" can run Processing (C++) with 23 bits of precision in less than 212us and the necessary code smaller than 205 instructions. May be if C++ uses CORDIC.  Arduino sketches can import assembly code.
Makes no sense to post the code here, later I will edit this post to include a weblink to it, possibly on my blog at this url. The blog is mostly in portuguese.
This hobby-no-money venture was interesting, pushing the limits of the AVR engine of almost 16MIPS at 16MHz, without division instruction, multiplication only in 8x8 bits.  It allows to calculate sin(x), cos(x) [=sin(900-x)] and tan(x) [=sin(x)/sin(900-x)].
Above it all, this helped to keep my 63 years old brain polished and oiled. When teenagers say the 'old people' know sh*nothing about technology, I answer "think again, who do you think created the bases for everything you enjoy today?".
Cheers

Nice! A few remarks: 1. The standard sin() function has about the same accuracy as yours and is twice as fast. It is also based on a polynomial. 2. If an arbitrary angle has to be rounded to the nearest multiple of 0.1°, this can lead to a rounding error as high as 8.7e-4, which sort of negates the benefit of the 23 bit accuracy. 3. Would you mind sharing your polynomial?

I had a simillar question to OP. I wanted to make a LUT table to calculate the first quadrant of the sine function as unsigned 16 bit integers starting from 0x8000 to 0xffff. And i ended up writing this for fun and profit. Note: This would work more efficiently if i used 'if' statements. Also it's not very accurate, but would be accurate enough for a sine wave in a sound synthesiser
void sin_lut_ctor(){

//Make a Look Up Table for 511 terms of the sine function.
//Plugin in some polynomials to do some magic
//and you get an aproximation for sines up to π/2.
//

//All sines yonder π/2 can be derived with math

const uint16_t uLut_d = 0x0200; //maximum LUT depth for π/2 terms.
uint16_t uLut_0[uLut_d];        //The LUT itself.
//Put the 2 above before your void setup() as global variables.
//This coefficients will only work for uLut_d = 511.

uint16_t arna_poly_0 = 0x000a; // 11
uint16_t arna_poly_1 = 0x0001; // 1
uint16_t arna_poly_2 = 0x0007; // 7
uint16_t arna_poly_3 = 0x0001; // 1   Precalculated Polynomials
uint16_t arna_poly_4 = 0x0001; // 1
uint16_t arna_poly_5 = 0x0007; // 7
uint16_t arna_poly_6 = 0x0002; // 2
uint16_t arna_poly_7 = 0x0001; // 1

uint16_t Imm_UI_0 = 0x0001;              //  Itterator
uint16_t Imm_UI_1 = 0x007c;              //  An incrementor that decreases in time

uint16_t Imm_UI_2 = 0x0000;              //
uint16_t Imm_UI_3 = 0x0000;              //
uint16_t Imm_UI_4 = 0x0000;              //
uint16_t Imm_UI_5 = 0x0000;              //
uint16_t Imm_UI_6 = 0x0000;              //  Temporary variables
uint16_t Imm_UI_7 = 0x0000;              //
uint16_t Imm_UI_8 = 0x0000;              //
uint16_t Imm_UI_9 = 0x0000;              //
uint16_t Imm_UI_A = 0x0000;
uint16_t Imm_UI_B = 0x0000;

uint16_t Imm_UI_A = uLut_d - 0x0001;     //  510

uLut_0[0x0000] = 0x8000;        //Assume that the middle point is 32768 (0x8000 hex)
while (Imm_UI_0 < Imm_UI_A) //Construct a quarter of the sine table
  {
Imm_UI_2++;                                   //Increase temporary variable by 1

Imm_UI_B = Imm_UI_2 / arna_coeff_0;           //Divide it with the first coefficient (note: integer division)
Imm_UI_3 += Imm_UI_B;                         //Increase the next temporary value if the first one has increased up to the 1st coefficient
Imm_UI_1 -= Imm_UI_B;                         //Decrease the incrementor if this is the case
Imm_UI_2 *= 0x001 - Imm_UI_B;                 //Set the first temporary variable back to 0

Imm_UI_B = Imm_UI_3 / arna_poly_1;           //Do the same thing as before with the next set of temporary variables
Imm_UI_4 += Imm_UI_B;
Imm_UI_1 -= Imm_UI_B;
Imm_UI_3 *= 0x0001 - Imm_UI_B;

Imm_UI_B = Imm_UI_4 / arna_poly_2;           //And again... and again... you get the idea.
Imm_UI_5 += Imm_UI_B;
Imm_UI_1 -= Imm_UI_B;
Imm_UI_4 *= 0x0001 - Imm_UI_B;

Imm_UI_B = Imm_UI_5 / arna_poly_3;
Imm_UI_6 += Imm_UI_B;
Imm_UI_1 -= Imm_UI_B;
Imm_UI_5 *= 0x0001 - Imm_UI_B;

Imm_UI_B = Imm_UI_6 / arna_poly_4;
Imm_UI_7 += Imm_UI_B;
Imm_UI_1 -= Imm_UI_B;
Imm_UI_6 *= 0x0001 - Imm_UI_B;

Imm_UI_B = Imm_UI_7 / arna_poly_5;
Imm_UI_8 += Imm_UI_B;
Imm_UI_1 -= Imm_UI_B;
Imm_UI_7 *= 0x0001 - Imm_UI_B;

Imm_UI_B = Imm_UI_8 / arna_poly_6;
Imm_UI_9 += Imm_UI_B;
Imm_UI_1 -= Imm_UI_B;
Imm_UI_8 *= 0x0001 - Imm_UI_B;

Imm_UI_B = Imm_UI_9 / arna_poly_7          //the last set won't need to increment a next variable so skip the step where you would increase it.
Imm_UI_1 -= Imm_UI_B;
Imm_UI_9 *= 1 - Imm_UI_B;

uLut_0[Imm_UI_0] = (uLut_0[Imm_UI_0 - 0x0001] + Imm_UI_1); //Set the current value as the previous one increased by our incrementor
Imm_UI_0++;              //Increase the itterator
  }
  uLut_0[Imm_UI_A] = 0xffff; //Lastly, set the last value to 0xffff

  //And there you have it. A sine table with only one if statement (a while loop)
}

Now to get back the values, use this function.It accepts a value from 0x0000 to 0x0800 and returns the appropriate value from the LUT
uint16_t lu_sin(uint16_t lu_val0)
{
  //Get a value from 0x0000 to 0x0800. Return an appropriate sin(value)
  Imm_UI_0 = lu_val0/0x0200; //determine quadrant
  Imm_UI_1 = lu_val0%0x0200; //Get which value
  if (Imm_UI_0 == 0x0000)
  {
    return uLut_0[Imm_UI_1];
  }
  if (Imm_UI_0 == 0x0001)
  {
    return uLut_0[0x01ff - Imm_UI_1];
  }
  if (Imm_UI_0 == 0x0002)
  {
    return 0xffff - uLut_0[Imm_UI_1];
  }
  if (Imm_UI_0 == 0x0003)
  {
    return 0xffff - uLut_0[0x01ff - Imm_UI_1];
  }
}// I'm using if statements here but similarly to the above code block,
 //you can do without. just with integer divisions and modulos

Remember, this is not the most efficient approach to this task, i just couldn't figure out how to make taylor series to give out results in the appropriate range.

Your code doesn't compile: Imm_UI_A is declared twice, a ; and some variable declarations are missing, and uLut_0 should be global. With the necessary fixes, lu_sin() is fast (between 27 and 42 CPU cycles) but very inaccurate (maximum error ≈ 5.04e-2). I can't get the point of these “Arnadathian polynomials”: it seems quite a heavy computation, yet the result is almost as bad as a simple quadratic approximation. The method also has a huge memory cost. It would be way better to compute the table on your PC and put it in the source code as a PROGMEM array.

As others have mentioned lookup tables are the way to go if you want speed. I've recently been investigating computation of trig functions on an ATtiny85 for use of fast vector averages (wind in my case). There's always trade off's...for me I only needed 1 deg angular resolution so a lookup table of 360 int's (scaling -32767 to 32767, only working with int's) was the best way to go. Retrieving the sine is just a matter of supplying an index 0-359...so very fast! Some numbers from my tests:
FLASH lookup time (us): 0.99 (table stored using PROGMEM)
RAM lookup time (us): 0.69 (table in RAM)
Lib time (us): 122.31 (Using Arduino Lib)
Note these are averages across a 360 point sample for each. Testing was done on a nano.

generally, look-up table > approximation -> calculation. ram > flash. integer > fixed point > floating point. pre-calclation > real time calculation. mirroring (sine to cosine or cosine to sine) vs. actual calculation / look-up....
each has its pluses and minuses.
you can make all sorts of combinations to see which works best for your application.
edit: I did a quick checking. using 8-bit integer output, calculating 1024 sin values with look-up table takes 0.6ms, and 133ms with floaters, or 200x slower.


text:
How to control PWM and digital pins at the same time over ethernet in arduino
I am using Controllino Maxi. It has an Arduino Uno inside it. I am trying to control the PWM pin D0 and digital pin R0 via python code. Below is the code I have upload on arduino:
Arduino Code:
#include <Ethernet.h>
#include <EthernetUdp.h>
#include <SPI.h>
#include <Controllino.h>

byte mac[] ={};
IPAddress ip(192, 168, 0, 200);
unsigned int localPort = 5000;
char packetBuffer[UDP_TX_PACKET_MAX_SIZE];
String datReq;
int packetSize;
EthernetUDP Udp;

void setup()
{
  Ethernet.begin( mac, ip);
  Udp.begin(localPort); //Initialize Udp
  pinMode(CONTROLLINO_D0, OUTPUT);
  pinMode(CONTROLLINO_R0, OUTPUT);

}

void loop() {
  packetSize =Udp.parsePacket(); //Reads the packet size
  if(packetSize>0)
  {
    Udp.read(packetBuffer, UDP_TX_PACKET_MAX_SIZE); //Read the data request
    String datReq(packetBuffer);
    if (datReq == "R0")
    {
      digitalWrite(CONTROLLINO_R0, HIGH);
      delay(2000);
      digitalWrite(CONTROLLINO_R0, LOW);
    }
    else
    {
      analogWrite(CONTROLLINO_D0, datReq.toInt());
      delay(2000);
      analogWrite(CONTROLLINO_D0, 0);
    }
  }
 }

In above code, if I receive R0 over ethernet, then I am turning on/off R0 pin, else whatever PWM I am receiving, I am setting it using analogWrite. Below is my python code:
from socket import *
import time

address = ('192.168.0.200', 5000)  # define server IP and port ((0x12, 0x02, 0x00, 0x00, 0xEA, 0x03))
client_socket = socket(AF_INET, SOCK_DGRAM)  # Set up the Socket
client_socket.settimeout(1)

data = "R0".encode("utf-8")
client_socket.sendto(data, address)
time.sleep(5)

data = ("{}".format(200)).encode("utf-8")
client_socket.sendto(data, address)
time.sleep(5)

data = ("{}".format("R0")).encode("utf-8")
client_socket.sendto(data, address)

In above code, I am first sending R0 to turn on/off R0 and then sending 200 for PWM and then again sending R0 to turn on/off R0. When tested I can see R0 getting high and low, then I can see 200 on PWM but then again R0 should be high/low but it stays low. If  I re run the python code, R0 doesnt work and only PWM works. If I power off the board and power it again, then R0 works only for first time and it didnt work in second time.
I am a bit confused at this stage. Is there any bug in my arduino code as I am not very experienced in it. Is there any way to debug it? Please help. THanks

You Arduino sketch is storing the received UDP packet in a char array
named packetBuffer, then converting this array to a String object
like this:
String datReq(packetBuffer);

The problem is that this String constructor expects a NUL-terminated
array, and you have no guarantee that this array is NUL-terminated.
Well, actually you have this guarantee, but only at the beginning: as
the program starts, the array will be filled with zeros by the C
initialization routine. This is why the first request is correctly
processed. The second request sends a packet larger than the first one,
so the array is still NUL-terminated. On the third request, however, the
received bytes are immediately followed by the leftovers of the previous
request. In this case it is the digit '0'.
The simple solution is to ensure that the buffer is always properly
terminated. Start by making it wider by one byte:
char packetBuffer[UDP_TX_PACKET_MAX_SIZE + 1]; // +1 for the '\0'

Then, whenever you receive a packet, add the terminating NUL character:
Udp.read(packetBuffer, UDP_TX_PACKET_MAX_SIZE); //Read the data request
packetBuffer[packetSize] = '\0'; // properly terminate the buffer


text:
connecting 4 scales to microcontroller for use as dog force plate
I want to build a system to measure the force distribution between the 4 legs of a dog. I plan to use this method:
http://www.rehabtools.org/scales.html
This setup seems to be for 1 scale. I want to use 1 scale for each leg, so that adds up to  4 scales. I assume I need 4 amplifiers, but can I connect those 4 to one microcontroller?
I currently have the Arduino Uno coming, will that work?
The connection from the 4 legs of the scale to the load amplifier I understand. But how do I go about having the 4 readings and then getting them in the software program?
Any advice would be greatly appreciated.

use the search terms arduino load cell in your research

If you follow the links in the tutorial you linked to, you will find

this library for interfacing the HX711 load-cell amplifier

this example sketch for reading the scale

The library uses a bit-banging method (pulseIn()) for communicating
with the amplifier. This method can work with any of the Arduino
digital pins. In the example sketch you have the instantiation:
HX711 scale(3, 2);

where the numbers (3, 2) tell the library the pins you want to use.
Given all this, you should be able to interface four identical scales
simply by using four separate pairs of pins. For example:
HX711 scale1(3, 2);
HX711 scale2(5, 4);
HX711 scale3(7, 6);
HX711 scale4(9, 8);

The adapt the example sketch to read all the scales.


text:
Combining esp_wakeup_timer with external interrupt ext0
I'm working with ESP32-Dev-Kit1 and MMA8452Q accelerometer. I want the ESP to read the accelerometer for 10s, then go to sleep for 10s. If within the sleep period, the accelerometer magnitude reading exceeds the threshold, it will also wake up the ESP.
#include <Wire.h>
#include "SparkFun_MMA8452Q.h"

MMA8452Q accel;

void setup()
{
  Serial.begin(9600);
  Serial.println("MMA8452Q Test Code!");

  accel.init(SCALE_2G, ODR_6);

  // Configure the wake-up source
  esp_sleep_enable_ext0_wakeup(GPIO_NUM_33, 0); // GPIO 33, HIGH logic level
}

void loop()
{
  // Read accelerometer and print values for 10 seconds
  unsigned long startTime = millis();
  unsigned long duration = 10000; // 10 seconds
  while (millis() - startTime < duration) {
    if (accel.available()) {
      accel.read();
      printCalculatedAccels();
    }
  }

  // Sleep for 10 seconds or wake up immediately if magnitude > 1.0
  Serial.println("Going to sleep or waking up if magnitude exceeds 1.0...");
  Serial.flush(); // Ensure all serial data is sent
  float magnitude = sqrt(pow(accel.cx, 2) + pow(accel.cy, 2) + pow(accel.cz, 2));
  if (magnitude > 1.0) {
    Serial.println("Magnitude exceeded 1.0, waking up...");
    esp_sleep_enable_ext0_wakeup(GPIO_NUM_33, 1);
    esp_deep_sleep_start();

  } else {
    esp_sleep_enable_timer_wakeup(10 * 1000000); // 10 seconds
    esp_deep_sleep_start();
  }
}

void printCalculatedAccels()
{
  Serial.print(accel.cx, 3);
  Serial.print("\t");
  Serial.print(accel.cy, 3);
  Serial.print("\t");
  Serial.print(accel.cz, 3);
  Serial.println("\t");
}

start by reducing your code to only the sleep code ... remove all of the accelerometer code ... when the 10 second sleep works, then add the accel code

I made some small changes to my code. Now, it works fine by sleeps for 10 seconds and triggers when the threshold is exceeded. But there's a problem about the threshold trigger part: the ext0 wakeup function activates only before it enters sleep mode. Once the ESP is sleeping, it only wakes up using the timer, not by ext0 interrupt.
is there something I miss in configuration?


text:
Best practices for really long distance sensor deployments
I'm noob to Arduino and electronics, but here is a problem from life which I need to solve for myself:
We grow strawberries and early spring freezes can take most of the flowers from the plants. One way to protect this is to have some kind of heating in solar houses, but if you grow outside, your best option is to watering the flowers on the crops when the freezing comes.
I want to deploy at least 3-4 temperature sensors, which are placed at every parts of the land, which will send the data for an Arduino which will turn on the pump with a relay (for this part I also want to use a pre-built relay solution with socket plugs already built, I don't want to mess around with high electricity myself).
For a cable solution (like catKIT system) I need at least 100m cable for the farest part of the land, which can be managable, but later on, scaling the land lots of cables everywhere can be a problem.
So the best solution would be if every temperature sensor is a standalone station, data transmitted by wireless to the main Arduino which is triggering the pump. This way there will be lass cables on the land, less change to cable break by tractor, etc.
Also, with a wireless system, I don't have to deal with signal loss over the cable, just only wireless signal loss. Is it possible to correct this by middle wireless signal transmitter stations? Or even better, all of them connected to each other!?
Like if the farest sensor reading Celsius 0.8, middle sensor reading Celsius 1.2. Middle sensor have a variable to also consider any reading from the farest sensor, which is reading 0.8. If that reading under Celsius 1, than don't bother his own output, send 0.8 to the main Arduino which is triggering the pump.
These station's power input still need to be solved, but maybe solar panels can be an option? However I have a clue that night they will not work, most of them freezing comes at night.
I saw wireless shields for arduino which offering even a km range in ideal conditions. But how degrading when the conditions are not ideal, like a house wall, rain, fog, snow?
Is it possible to feed multiple wireless inputs too one arduino? 3-4-10-20 standalone stations which transmitting temperature reads for the main arduino. If one of them sends lower temperature than +1 Celsius, than the pump will be turned on. Is it possible to solve this?
Thank You for your answers!

Is temperature really that different, in different locations? I'd go with a single sensor, and maybe a larger safety margin of e.g. 1.5 degrees C. Don't make things too complicated.

Probably not, but in altitude can be a difference (0 to 200cm, if we implement vertical towers). Also consider the environment (open vs tree shades). Happened in our garden that the flowers at open field frozen, the ones was in little shade won't. Covering the entire land with sensors just saves it from partial freezing, which can be still relevant.

Seems like you already know where the coldest spot is. Just place the one sensor there (on ground level).

There's as many ways of solving your problem as there are of skinning a cat (those poor poor cats - always getting skinned... ;) )
As you have already noted there are two basic solutions: wired or wireless.
Wired does have one major advantage that you haven't really touched on (only mentioned in passing) and that is power. With a wired solution you can provide power over those same wires so you don't need to worry about solar panels, batteries, whatever. But wires can break, yes. So they're not ideal. But then what is?
With wireless you then introduce the major problem of power. Solar panels are one possible way of getting power, though they are expensive, and you need to "over spec" them to charge batteries so you continue to have enough power for the times when is little or no sun.  Complementing them with wind power is also an option to boost the battery charge when its windy. It all adds up to very expensive sensors though.
A compromise might be to consider both options together.  Turn the sensors into small clusters of sensors that are near by with a base station for those sensors that both gathers and stores the power needed for them, and performs the wireless communication. The sensors would then be wired to the base station.  Your wires are then shorter, and your power is more centralised.
But what to then use for the wireless itself? Well, there it's really all down to frequency.  There's two basic gropings here:

High frequency - 2.4GHz - is great at unobstructed communication. That's the frequency your WiFi works on, and as you probably know it's great if there's no walls in the way. Add walls and the signal drops off considerably.
Low frequency - 433MHz - Far far better at penetrating walls and things but much less bandwidth.

I have had distances of hundreds of meters using a 2.4GHz nRF24L01+ module with power amplifier and antenna. That's in open air with (pretty much) line of sight. Indoors the range is much much shorter. Put buildings in the way and your hundreds of meters drop down to tens of meters.
So if there are obstructions you're pretty much going to want to use the 433MHz range (there is another frequency, which is different depending on where in the world you are - 868MHz or 915MHz, so we'll ignore that for now).
There's plenty of modules around that run at 433MHz, some better than others. There is, however, a new standard emerging now that is designed specifically for this kind of thing - long range, low bandwidth, just for sensors (as part of the IoT bandwagon) called LoRa (short for Long Range) which aims at distances of 15km using very small amounts of power (tens of mA) which is ideal for solar powered operation. It also can use the 868/915MHz region as well.
The final option that you touched on without knowing it is that of a mesh. This is where all the nodes form a network and each node is capable of relaying data from other nodes to get to their destination. Kind of like how the internet works. There are some mesh libraries available for some radio modules on the Arduino, but I have no idea how good or reliable they are. The best ones would be completely self-healing with auto-discovery - add a node and the whole mesh works out how to route messages to the destination node; remove a node and the mesh works out new routes to pass the data around the hole it's created.
Creating a good mesh stack is not child's play, so you would want to research it properly and find the best modules with the best library support if you wanted to take this route. That's why LoRa is taking off - it's so much simpler to get wide coverage without the need of complex mesh systems.

Personally I wouldn't use an Arduino as a wireless sensor controller, I would use an ESP8226, which comes with WIFI interface built in.  You can program this through the Arduino IDE in the same language, and its compatible with most Arduino sensors.
The ESP8266 also has the advantage that it can create a WIFI network of its own, because it can act as a WIFI client, a WIFI access point or both at the same time.  So if you do have an issue with the range of the signals then you can program your own WIFI repeater, which could also measure the temperature at the same time.   They come in many different shapes and sizes, I think you might be better having an external aerial capability, have a look around and see what you can find.  They cost around $2 so they should break the bank.
As for powering it you could use solar or wind power to charge a battery.  Probably the best sort of battery for this is a Lead Acid battery because they don't object to being trickle charged.  Assuming you sensor station runs at 5V, you want at least a 6V battery.  You charge a 6V battery at 7.2V, so your solar panel(s) should generate at least 7.2V in average sunshine.  You also need to work out how much power you sensor station is going to need, factor in an extra for working in cold weather, etc and then multiply it by the number of hours per day want it to work (24?).  This is the total power you need per day, so the output of you panels must be = (Required Power / Hours of Sun).  At this point you are best looking for a COTs device to charge the batteries and achieve your needs.


text:
Informations lost in a string
At first, I sorry if I make some English faults but I'm French.
So, I'm making a connection between a client and an Arduino Uno. I receive all data that I need but when I send a response to my client some characteres are lost.
I receive this format : GET /?b=7&p=100$ (for exemple)
And my Arduino sends this to my client : GET /?b=7&p=1d
This is the function where I get all data from my client :
void read_data(int *state, int *progress_program){
  // Check if there is a client
  EthernetClient client = server.available();
  if (client) {
    url = "";
    index = 0;
    Serial.println("\nnew client");
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        Serial.println(c);
       if(c != '$') { // if end of char
          url[index] = c;
          index++;
        } else {
          url[index] = '\0';
          int i;
         Serial.print("\n");
          for(i=0;i<index;i++)
            Serial.print(url[i]);
          if(interpret(state, progress_program)){
            action();
            delay(100);
          }
          answer(client);
          break;
        }
      }
    }
    url[0] = '\0';
    // give the web browser time to receive the data
    client.stop();
    delay(100);
    Serial.println("\nclient disconnected");
  }
}

And the response sent to the client :
void answer(EthernetClient client){
  Serial.print("\nResponse"); // debug
  delay(100);
  client.print(url);
  Serial.print("Response Sent");
  delay(100);
}

With client.write(url) there is the same problem.
Have you got a solution?
thanks

How did you declare url? It should be an array, not a pointer.

I declare url like this : char *url = (char *)malloc(100);
But it's ok, my error was url = "";
With url[0] = '\0'; it's works !
Thanks

@electro I suggest you post that as an answer then. In time (with extra rep) you'll be able to then accept it as the correct answer and people with a similar problem will be able to find help easily. Be sure to detail just what the problem was and why it was a problem (what the effect of url=""; is)

So, the solution was very simple,
My pointer "url" received a constant null string with url=""; at the beginning. To initialize a string as null we need to make this :
 url[0] = '\0';

thanks