text:
Arduino Mega with Sensors and tftlcd 2.4 inch
I am working with tftlcd 2.4 inch with Arduino mega 2560 board. In this code I just want to show clock as my default or home screen. By clicking on clock at any point on screen user should get a new screen in which options of three sensors(pulse oximeter, glucose sensor and pedometer) are available. By selecting any sensor by touch, the value of that sensor will appear on screen. I also want to use Bluetooth module to send data to my mobile application. I did separate integration of all these sensors with Bluetooth module HC -06, but now I want to compile my all work. I have write a code for all this procedure which is given below:
    #include <Adafruit_GFX.h>

#include <Adafruit_TFTLCD.h>
#include <TouchScreen.h>
//#include <URTouch.h>
#include <Wire.h>
#include "MAX30105.h"
#include "spo2_algorithm.h"

MAX30105 particleSensor;

#define YP A2
#define XM A3
#define YM 8
#define XP 9
#define TS_MINX 275
#define TS_MINY 648
#define TS_MAXX 1023
#define TS_MAXY 623
#define MINPRESSURE 10
#define MAXPRESSURE 1000
#define LCD_CS A3
#define LCD_CD A2
#define LCD_WR A1
#define LCD_RD A0
#define LCD_RESET A4
#define MAX_BRIGHTNESS 255

TouchScreen ts = TouchScreen(XP, YP, XM, YM, 300);
Adafruit_TFTLCD tft(LCD_CS,LCD_CD, LCD_WR, LCD_RD, LCD_RESET);

#if defined(__AVR_ATmega328P__) || defined(__AVR_ATmega168__)
uint16_t irBuffer[100];
uint16_t redBuffer[100];
#else
uint32_t irBuffer[100];
uint32_t redBuffer[100];
#endif

boolean buttonEnabled =true;
char currentpage, currentpcolour;
bool running;
//clock
uint16_t osx = 120, osy = 120, omx = 120, omy = 120, ohx = 120, ohy = 120, xpos;
uint32_t targetTime = 0;
uint8_t conv2d(const char* p) {
  uint8_t v = 0;
  if ('0' <= *p && *p <= '9')
    v = *p - '0';
  return 10 * v + *++p - '0';
}
uint8_t hh = conv2d(__TIME__), mm = conv2d(__TIME__ + 3), ss = conv2d(__TIME__ + 6);
boolean initial = 1;
char d;

//PulseOxi
int32_t bufferLength, spo2, heartRate; //data length, SPO2 value, heart rate value
int8_t validSPO2, validHeartRate; //indicator to show if the SPO2 calculation is valid, indicator to show if the heart rate calculation is valid
byte pulseLED = 11; //Must be on PWM pin
byte readLED = 13; //Blinks with each data read
byte ledBrightness = 60; //Options: 0=Off to 255=50mA
byte sampleAverage = 4; //Options: 1, 2, 4, 8, 16, 32
byte ledMode = 2; //Options: 1 = Red only, 2 = Red + IR, 3 = Red + IR + Green
byte sampleRate = 100; //Options: 50, 100, 200, 400, 800, 1000, 1600, 3200
int pulseWidth = 411; //Options: 69, 118, 215, 411
int adcRange = 4096; //Options: 2048, 4096, 8192, 16384

//Pedometer
const int xpin = A1;
const int ypin = A2;
const int zpin = A3;
byte p[8] = {
  0x1F,
  0x1F,
  0x1F,
  0x1F,
  0x1F,
  0x1F,
  0x1F,
  0x1F
};
float threshold = 100;
float xval[100] = {0};
float yval[100] = {0};
float zval[100] = {0};
float xavg, yavg, zavg;
int steps, flag = 0;

void drawClock(){
  tft.setTextColor(0xFFFF);
  tft.fillScreen(0x0000);
  xpos = tft.width() / 2;
  tft.drawCircle(xpos, 120, 125, 0xFFE0);
  tft.fillCircle(xpos, 120, 118, 0x001F);
  tft.fillCircle(xpos, 120, 110, 0x0000);
  for (int a=95; a<104; a++){
    tft.drawCircle(xpos, 120, a, 0xFFFF);
  }
  for (int i = 0; i < 360; i += 30) {
    tft.drawLine(((cos((i - 90) * 0.0174532925)) * 114 + xpos), ((sin((i - 90) * 0.0174532925)) * 114 + 120), ((cos((i - 90) * 0.0174532925)) * 100 + xpos), ((sin((i - 90) * 0.0174532925)) * 100 + 120), 0xFFE0);
  }
  for (int i = 0; i < 360; i += 6) {
    tft.drawPixel(((cos((i - 90) * 0.0174532925)) * 102 + xpos), ((sin((i - 90) * 0.0174532925)) * 102 + 120), 0x07E0);
    tft.drawLine(((cos((i - 90) * 0.0174532925)) * 102 + xpos), ((sin((i - 90) * 0.0174532925)) * 102 + 120), ((cos((i - 90) * 0.0174532925)) * 92 + xpos), ((sin((i - 90) * 0.0174532925)) * 92 + 120), 0x0000);
    tft.drawLine(((cos((i - 90) * 0.0174532925)) * 102 + xpos)+1, ((sin((i - 90) * 0.0174532925)) * 102 + 120)+1, ((cos((i - 90) * 0.0174532925)) * 92 + xpos)+1, ((sin((i - 90) * 0.0174532925)) * 92 + 120)+1, 0x0000);

    if (i == 0 || i == 180) tft.fillCircle(((cos((i - 90) * 0.0174532925)) * 102 + xpos), ((sin((i - 90) * 0.0174532925))* 102 + 120), 2, 0xFFFF);
    if (i == 90 || i == 270) tft.fillCircle(((cos((i - 90) * 0.0174532925)) * 102 + xpos), ((sin((i - 90) * 0.0174532925))* 102 + 120), 2, 0xFFFF);
  }
  tft.fillCircle(xpos, 121, 3, 0xFFFF);
  targetTime = millis() + 1000;
}

void setup() {
  tft.reset();
  tft.begin(0x9341);
  tft.setRotation(1);
  digitalWrite(13, HIGH);
  //TSPoint p = ts.getPoint();     // Read touchscreen
  digitalWrite(13, LOW);
  pinMode(XM, OUTPUT);
  pinMode(YP, OUTPUT);
  pinMode(pulseLED, OUTPUT);
  pinMode(readLED, OUTPUT);
  //first screen
  drawClock();
  currentpage = '0';
}

void loop() {
if (currentpage == '0') {
  TSPoint p = ts.getPoint();
  if (p.z > ts.pressureThreshhold) {
      p.x = map(p.x,TS_MAXX, TS_MINX , 0, 320);
      p.y = map(p.y,TS_MAXY, TS_MINY , 0, 480);
      if (p.x > 50 && p.x > 260 && p.y > 180 && p.y < 270 && buttonEnabled){
        buttonEnabled = false;
        tft.fillScreen(0x0000);
        currentpage = '1';
        drawHomeScreen();
      }
  }
}
   if (currentpage == '1') {
    TSPoint p = ts.getPoint();
     if (p.z > 10 && p.z < 1000) {
        if (p.x > 736 && p.x < 855 && p.y > 255 && p.y < 725  && p.z > MINPRESSURE && p.z < MAXPRESSURE)
        {
        Serial.println("Pedometer");
        currentpage = 2;
        calibrate();
      }
      else if (p.x > 563 && p.x < 683 && p.y > 275 && p.y < 750)
      {
        currentpage = 3;
        //drawGlu();
      }
      if (p.x > 403 && p.x < 525 && p.y > 271 && p.y < 725)
      {
        if (!particleSensor.begin(Wire, I2C_SPEED_FAST)) //Use default I2C port, 400kHz speed
             {
              Serial.println(F("MAX30105 was not found. Please check wiring/power."));
              while (1);
             }
             Serial.println(F("Attach sensor to finger with rubber band. Press any key to start conversion"));
             while (Serial.available() == 0) ; //wait until user presses a key
             Serial.read();
             particleSensor.setup(ledBrightness, sampleAverage, ledMode, sampleRate, pulseWidth, adcRange); //Configure sensor with these settings
             currentpage = '4';
             drawPulseOxi();
      }
    }
  }
if (currentpage == '0') {
    if (targetTime < millis()) {
      targetTime = millis() + 1000;
      ss++;
      if (ss == 60) {
        ss = 0;
        mm++;
        if (mm > 59) {
          mm = 0;
          hh++;
          if (hh > 23) {
            hh = 0;
        }
      }
    }
 if (ss == 0 || initial) {
      initial = 0;
      // Erase hour and minute hand positions every minute
      tft.drawLine(ohx, ohy, xpos, 121, 0x0000);
      ohx = (cos(((hh * 30 + (mm * 6 + (ss * 6) * 0.01666667) * 0.0833333) - 90) * 0.0174532925)) * 62 + xpos + 1;
      ohy = (sin(((hh * 30 + (mm * 6 + (ss * 6) * 0.01666667) * 0.0833333) - 90) * 0.0174532925)) * 62 + 121;
      tft.drawLine(omx, omy, xpos, 121,  0x0000);
      omx = (cos(((mm * 6 + (ss * 6) * 0.01666667)- 90) * 0.0174532925)) * 84 + xpos;
      omy = (sin(((mm * 6 + (ss * 6) * 0.01666667) - 90) * 0.0174532925)) * 84 + 121;
    }
      // Redraw new hand positions, hour and minute hands not erased here to avoid flicker
      tft.drawLine(osx, osy, xpos, 121,  0x0000);
      osx = (cos(((ss * 6) - 90) * 0.0174532925)) * 90 + xpos + 1;
      osy = (sin(((ss * 6) - 90) * 0.0174532925)) * 90 + 121;
      tft.drawLine(osx, osy, xpos, 121, 0xF800);
      tft.drawLine(ohx, ohy, xpos, 121, 0x07FF);
      tft.drawLine(omx, omy, xpos, 121, 0xFFFF);
      tft.drawLine(osx, osy, xpos, 121, 0xF800);
      tft.fillCircle(xpos, 121, 3, 0xF800);
      tft.setCursor(xpos-27, 50);
      tft.setTextSize(2);
      tft.print("Glucoxy");

  // Draw MINI clock face "SECOND"
  tft.drawCircle(xpos, 155, 20, 0xFFE0);
  tft.drawCircle(xpos, 155, 18, 0x001F);
  tft.drawCircle(xpos, 155, 17, 0x07FF);
  tft.drawCircle(xpos, 155, 16, 0x07FF);
  tft.fillRect(xpos-10, 149,22,15,0x0000); //erase
  if(ss<10){tft.setCursor(xpos-10, 149); tft.setTextSize(2);
  tft.print('0'); tft.setCursor(xpos+2, 149);}
  else{
  tft.setCursor(xpos-10, 149);}
  tft.setTextSize(2);
  tft.print(ss);
  // Draw MINI clock face "Minutes"
  tft.drawCircle(xpos+35, 117, 20, 0xFFE0);
  tft.drawCircle(xpos+35, 117, 18, 0x001F);
  tft.drawCircle(xpos+35, 117, 17, 0x07FF);
  tft.drawCircle(xpos+35, 117, 16, 0x07FF);
  tft.fillRect(xpos+25, 111,22,15, 0x0000); //erase
  if(mm<10){tft.setCursor(xpos+25, 111); tft.setTextSize(2);
  tft.print('0'); tft.setCursor(xpos+37, 111);}
  else{
  tft.setCursor(xpos+25, 111);}
  tft.println(mm);
  // Draw MINI clock face "Hour"
  tft.drawCircle(xpos-35, 117, 20, 0xFFE0);
  tft.drawCircle(xpos-35, 117, 18, 0x001F);
  tft.drawCircle(xpos-35, 117, 17, 0x07FF);
  tft.drawCircle(xpos-35, 117, 16, 0x07FF);
  tft.fillRect(xpos-45, 111,22,15,0x0000); //erase
  if(hh<10){tft.setCursor(xpos-45, 111); tft.setTextSize(2);
  tft.print('0'); tft.setCursor(xpos-33, 111);}
  else{
  tft.setCursor(xpos-45, 111);}
  tft.setTextSize(2);
  tft.print(hh);
  //tft.setCursor(xpos-65, 111);
  //tft.println(':');
  if (hh>=0 && hh<12) d='A'; else {d='P';}
  tft.drawRoundRect(xpos-14,72,29,21,5,0x07FF);
  tft.fillRect(xpos-11, 75,23,15,0x0000); //erase
  tft.setCursor(xpos-11, 75);
  tft.setTextSize(2);
  tft.print(d);
  tft.println('M');
  }
}
if (currentpage == '2')
{
    getPedo();
    TSPoint p = ts.getPoint();
    if (p.z > ts.pressureThreshhold)
    {
      p.x = map(p.x,TS_MAXX, TS_MINX ,0,320);
      p.y = map(p.y,TS_MAXY, TS_MINY ,0,480);
      if (p.x > 50 && p.x > 260 && p.y > 180 && p.y < 270 && buttonEnabled)
      {
         tft.fillScreen(0x0000);
         currentpage = '1';
         drawHomeScreen();
      }

   }
}
if (currentpage == '3')
{
     getGlucose();
     TSPoint p = ts.getPoint();
    if (p.z > ts.pressureThreshhold)
    {
      p.x = map(p.x,TS_MAXX, TS_MINX ,0,320);
      p.y = map(p.y,TS_MAXY, TS_MINY ,0,480);
      if (p.x > 50 && p.x > 260 && p.y > 180 && p.y < 270 && buttonEnabled)
      {
         tft.fillScreen(0x0000);
         currentpage = '1';
         drawHomeScreen();
       }
     }
}
if (currentpage == '4')
{
    getPulse();
    TSPoint p = ts.getPoint();
    if (p.z > ts.pressureThreshhold)
    {
      p.x = map(p.x,TS_MAXX, TS_MINX ,0,320);
      p.y = map(p.y,TS_MAXY, TS_MINY ,0,480);
      if (p.x > 50 && p.x > 260 && p.y > 180 && p.y < 270 && buttonEnabled)
      {
         tft.fillScreen(0x0000);
         currentpage = '1';
         drawHomeScreen();
      }
    }
}

}

void drawHomeScreen(){
  tft.fillScreen(0x0000);
  tft.drawRoundRect(0, 0, 319, 240, 8, 0xFFE0);     //Page border

  tft.fillRoundRect(60, 180, 200, 40, 8, 0x001F);
  tft.drawRoundRect(60, 180, 200, 40, 8, 0xFFE0);  //PEDO

  //tft.fillRoundRect(60, 130, 200, 40, 8, 0x001F);   //Glu
 // tft.drawRoundRect(60, 130, 200, 40, 8, 0xFFE0);

  tft.fillRoundRect(60, 80, 200, 40, 8, 0x001F);
  tft.drawRoundRect(60, 80, 200, 40, 8, 0xFFE0); //Pulse oxi and heart rate

  tft.setCursor(25, 20);
  tft.setTextSize(3);
  tft.setTextColor(0xFFFF);
  tft.print("Welcome Here..");
  tft.setCursor(25, 50);
  tft.setTextSize(2);
  tft.setTextColor(0xFFE0);
  tft.print("Choose Your Sensor");
  tft.setTextColor(0x0000);
  tft.setCursor(110, 195);
  tft.print("Pedometer");
  //tft.setCursor(80, 145);
  //tft.print("Glucose Sensor");
  tft.setCursor(80, 95);
  tft.print("Pulse Oximeter");
}
void drawPulseOxi()
{
  tft.setTextColor(0x0000);
  tft.fillRoundRect (60, 180, 200, 40, 8,0x0000);
  tft.setTextColor(0x001F);
  tft.drawRoundRect (10, 10, 60, 36, 8, 0x0000);
  tft.setCursor(18, 15);
  tft.setTextSize(3);
  //tft.fillScreen(0x0000);
  tft.print("<-" );
  tft.setCursor( 70, 18);
  //tft.fillScreen(0x0000);
  tft.setTextSize(1);
  tft.print("Back to Main Menu");
  tft.setCursor( 70, 18);
  tft.setTextSize(3);
  tft.print("Pulse Oximeter & Heart rate Sensor");
  tft.print("MAX30102");
  tft.setTextColor(0xFFFF);
  tft.drawLine(0,100,319,100, 0xFFFF);

  }
  void getPulse()
  {
    bufferLength = 100; //buffer length of 100 stores 4 seconds of samples running at 25sps
    for (byte i = 0 ; i < bufferLength ; i++)
   {
    while (particleSensor.available() == false) //do we have new data?
           particleSensor.check(); //Check the sensor for new data

    redBuffer[i] = particleSensor.getRed();
    irBuffer[i] = particleSensor.getIR();
    particleSensor.nextSample();
    Serial.print(F("red="));
    Serial.print(redBuffer[i], DEC);
    Serial.print(F(", ir="));
    Serial.println(irBuffer[i], DEC);
   }

  maxim_heart_rate_and_oxygen_saturation(irBuffer, bufferLength, redBuffer, &spo2, &validSPO2, &heartRate, &validHeartRate);

  while (1)
  {
    for (byte i = 25; i < 100; i++)
    {
      redBuffer[i - 25] = redBuffer[i];
      irBuffer[i - 25] = irBuffer[i];
    }

    for (byte i = 75; i < 100; i++)
    {
      while (particleSensor.available() == false) //do we have new data?
        particleSensor.check(); //Check the sensor for new data

      digitalWrite(readLED, !digitalRead(readLED)); //Blink onboard LED with every data read

      redBuffer[i] = particleSensor.getRed();
      irBuffer[i] = particleSensor.getIR();
      particleSensor.nextSample(); //We're finished with this sample so move to next sample

      //send samples and calculation result to terminal program through UART
      Serial.print(F("red="));
      Serial.print(redBuffer[i], DEC);
      Serial.print(F(", ir="));
      Serial.print(irBuffer[i], DEC);

      Serial.print(F(", HR="));
      Serial.print(heartRate, DEC);

      Serial.print(F(", HRvalid="));
      Serial.print(validHeartRate, DEC);

      Serial.print(F(", SPO2="));
      Serial.print(spo2, DEC);

      Serial.print(F(", SPO2Valid="));
      Serial.println(validSPO2, DEC);
    }

    //After gathering 25 new samples recalculate HR and SP02
     maxim_heart_rate_and_oxygen_saturation(irBuffer, bufferLength, redBuffer, &spo2, &validSPO2, &heartRate, &validHeartRate);
       tft.setCursor(77,20);
       tft.setTextColor(0x0000);
       tft.println("Oxygen level is:");
       tft.setCursor(77,23);
       tft.println(spo2);
       tft.setCursor(97,20);
       tft.setTextColor(0x0000);
       tft.println("Heart Rate is:");
       tft.setCursor(77,23);
       tft.println(heartRate);

}
}
void calibrate(){
  float sum = 0, sum1 = 0, sum2 = 0;
  for (int i = 0; i < 100; i++) {
    xval[i] = float(analogRead(xpin) - 345);
    sum = xval[i] + sum;
  }
  delay(100);
  xavg = sum / 100.0;
  Serial.println(xavg);
  for (int j = 0; j < 100; j++)
  {
    yval[j] = float(analogRead(ypin) - 346);
    sum1 = yval[j] + sum1;
  }
  yavg = sum1 / 100.0;
  Serial.println(yavg);
  delay(100);
  for (int q = 0; q < 100; q++)
  {
    zval[q] = float(analogRead(zpin) - 416);
    sum2 = zval[q] + sum2;
  }
  zavg = sum2 / 100.0;
  delay(100);
  Serial.println(zavg);

}
void getPedo(){
  int acc = 0;
  float totvect[100] = {0};
  float totave[100] = {0};
  float xaccl[100] = {0};
  float yaccl[100] = {0};
  float zaccl[100] = {0};
  for (int a = 0; a < 100; a++)
  {
    xaccl[a] = float(analogRead(xpin) - 345);
    delay(1);
    yaccl[a] = float(analogRead(ypin) - 346);
    delay(1);
    zaccl[a] = float(analogRead(zpin) - 416);
    delay(1);
    totvect[a] = sqrt(((xaccl[a] - xavg) * (xaccl[a] - xavg)) + ((yaccl[a] - yavg) * (yaccl[a] - yavg)) + ((zval[a] - zavg) * (zval[a] - zavg)));
    totave[a] = (totvect[a] + totvect[a - 1]) / 2 ;
    Serial.println("totave[a]");
    Serial.println(totave[a]);
    delay(100);
    if (totave[a] > threshold && flag == 0)
    {
      steps = steps + 1;
      flag = 1;
    }
    else if (totave[a] > threshold && flag == 1)
    {
      // Don't Count
    }
    if (totave[a] < threshold   && flag == 1)
    {
      flag = 0;
    }
    if (steps < 0) {
      steps = 0;
    }
    Serial.println('\n');
    Serial.print("steps: ");
    Serial.println(steps);
    delay(1000);

    tft.setCursor(77,10);
    tft.println("steps: ");
    tft.print(steps);

  }
  delay(1000);
}
void drawGlucose(){

}
void getGlucose(){

}

The problem I am facing here is that, when code is uploaded, then at start clock appear only for 2 sec then screen becomes white and nothing else is appeared on screen. Please point out my mistake in code given above. I give this code my full try but cannot get desired results.

Start removing stuff that isn't involved in demonstrating the problem.  The more you remove, the more likely you are to get help.


text:
TimedAction.h: No such file or directory
I am new to Arduino and I am trying one of the library TimedAction.h for sudo multithreading on Arduino. However the library is not present in the Arduino. How do I install external library(if it is)?

Have you googled how to install libraries? The [playground site]https://playground.arduino.cc/Code/TimedAction/) of that library even has a section about how to install it. Didn't it help you in some way?

You can use three ways to install libraries in the Arduino IDE:
The probably easiest way is to go to Sketch > Include Library > Manage Libraries, (you can use Ctrl+Shift+I too) search for the library you want to install and click the install button. After that you need to include the library in your sketch with a #include <LibraryName.h>, or if you don't know the name, head again to Sketch > Include Library and click on the library you want to include.
If a library is not in the Library Manager from step one, you have to download the .zip file, go to Sketch > Include Library > Add .ZIP Library and search for the file. You just have to do that once, and it will be moved to your library folder. Again, make sure to include the library into the sketch.
If you just have a single file, you can move it to the sketch folder and include it by using #include "LibraryName.h", but you have to do it all over again for a new sketch, so I would recommend the other solutions if you can and want to use it permanently.

source: Stack Exchange

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

sort: votes


text:
ESP32 Arduino Bluetooth Serial does not reconnect after disconnecting
The basic ESP32 Arduino Bluetooth Serial example pairs and connects as expected, BUT once I disconnect the Bluetooth terminal it stops responding to new events at all,
once I reset the esp32, it starts working again with the same problem. (it doesn't matter if it keeps being paired or not)
I have tested it with the windows Bluetooth terminal and with the Bluetooth Any terminal. (from the windows store)
I have downloaded the latest esp32-Arduino library from GitHub and I still get the same problem.
I have tested it with several esp32 modules, and they all respond with the same problem.
So it looks like a bug in the library code.
See the simple Arduino example code below:
#include "BluetoothSerial.h"

#if !defined(CONFIG_BT_ENABLED) || !defined(CONFIG_BLUEDROID_ENABLED) #error Bluetooth is not enabled! Please run make menuconfig to and enable it #endif

BluetoothSerial SerialBT;

void setup() { Serial.begin(115200); SerialBT.begin("ESP32test"); //Bluetooth device name Serial.println("The device started, now you can pair it with bluetooth!"); }

void loop() { if (Serial.available()) { SerialBT.write(Serial.read()); } if (SerialBT.available()) { Serial.write(SerialBT.read()); } delay(20); }

Does anyone know of another Bluetooth serial library that does work?
Thank You!

have you looked at the SerialToSerialBTM example code? ... it shows disconnect and reconnect

The SerialToSerialBTM example is for Bluetooth master mode, and not client mode

Nothing wrong with your code, I've the exact same issue as you have. It bothers me whole week long and fortunately, we (along with my colleague) accidentally figured that was caused by Windows 10, weird right? We don't believe it at very beginning either, but after several back-N-forth testing, it just like that. When we upload exact same code from another older computer with Windows 7 OS, it just works no matter how many time we connect/disconnect or even "QUIT" the APP without make it disconnect properly, its been able to be reconnect no problem. But once we use new computer with Windows 10 OS to upload the code, it can only be connected for first time, then stop broadcasting (or advertising).
The arduino official website in IDE download page also has a notice message "IMPORTANT: This app performs with core functionality on Windows 10 S but some limited plugins do not work. We are working with Microsoft on a fix.", hope this information helps.

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


text:
Thermistor returns correct value on Arduino Nano, completely fails on Arduino Uno Wifi Rev 2?
I am completely baffled. When I wire the thermistor into my Nano, everything reads completely fine. Then when I switch to the Uno Wifi Rev 2, I get negative numbers -40 to -80 when I was reading 24 on the Nano.
Wiring Diagram is:
           Thermistor
           |       |
Gnd---Resistor     Vcc
           |
       A6/A0 (6 for nano, 0 for Uno)

Code is:
#include <thermistor.h>
#define pin A6 //I change this to A0 on the WIfi. This is the only change
float temp;
uint32_t timeout = millis();
THERMISTOR thermistor(pin, //Analog pin
                  9800,    //Nominal res at 25 ºC
                  3559,    //Thermistor's B value
                  10000);  //Value of the resistor
void setup() {
  Serial.begin(9600);
}

void loop() {
  delay(1000);
  temp = thermistor.read();
  Serial.println(temp);
}

@timemage I just linked each boards store page, if thats what you wanted

It was.  There are significant differences between different boards carrying "Nano" and "UNO" in their names.

The Arduino UNO WiFi Rev2 defaults to an internal analog reference of 0.55V where the classic (non-"Every") Nano defaults to the external VCC voltage as a reference, which is usually around 5V, often a little lower because of the diode it uses between USB and "5V".
Either you need to be using the same voltage reference by selecting a common one with analogReference, or you need to use different references and calculate differently (or provide different values to the thermistor library) according to each reference.
If you've been using the VCC on the normal Nano board, you could try analogReference(VDD); on the UNO Wifi Rev 2.  This isn't necessary a great way to do it (probably using internal references would be better), but it is a simple way to get similar results on a UNO Wifi Rev2 without changing more than a single line to set the reference.


text:
AT command AT+CWJAP command always fail when connect to wifi

Refer to connect to wifi from https://www.cooking-hacks.com/mysignals-hw-ehealth-medical-biometric-iot-platform-arduino-tutorial.html
    #include <MySignals.h>
#include "Wire.h"
#include "SPI.h"

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

  MySignals.begin();

  //Enable WiFi ESP8266 Power -> bit1:1
  bitSet(MySignals.expanderState, EXP_ESP8266_POWER);
  MySignals.expanderWrite(MySignals.expanderState);

  MySignals.initSensorUART();

  MySignals.enableSensorUART(WIFI_ESP8266);
  delay(1000);

  // Checks if the WiFi module is started
  int8_t answer = sendATcommand("AT", "OK", 6000);
  if (answer == 0)
  {
    MySignals.println("Error");
    // waits for an answer from the module
    while (answer == 0)
    {
      // Send AT every two seconds and wait for the answer
      answer = sendATcommand("AT", "OK", 6000);
    }
  }
  else if (answer == 1)
  {

    MySignals.println("WiFi succesfully working!");

    if (sendATcommand("AT+CWMODE=1", "OK", 6000))
    {
      MySignals.println("CWMODE OK");
    }
    else
    {
      MySignals.println("CWMODE Error");

    }

    //Change here your WIFI_SSID and WIFI_PASSWORD
    if (sendATcommand("AT+CWJAP=\"WIFI_SSID\",\"WIFI_PASSWORD\"", "OK", 20000))
    {
      MySignals.println("Connected!");
    }
    else
    {
      MySignals.println("Error");

    }
  }
}

void loop()
{
  delay(5000);
}

int8_t sendATcommand(char* ATcommand, char* expected_answer1, unsigned int timeout)
{

  uint8_t x = 0,  answer = 0;
  char response[500];
  unsigned long previous;

  memset(response, '\0', sizeof(response));    // Initialize the string

  delay(100);

  while ( Serial.available() > 0) Serial.read();   // Clean the input buffer

  delay(1000);
  Serial.println(ATcommand);    // Send the AT command

  x = 0;
  previous = millis();

  // this loop waits for the answer
  do
  {

    if (Serial.available() != 0)
    {
      response[x] = Serial.read();
      x++;
      // check if the desired answer is in the response of the module
      if (strstr(response, expected_answer1) != NULL)
      {
        answer = 1;
        //MySignals.println(response);

      }
    }
    // Waits for the asnwer with time out
  }
  while ((answer == 0) && ((millis() - previous) < timeout));

  return answer;
}

I can't connect to router even i use the same SSID and password

print the response if answer is 0


text:
Using PWM pins on the UNO to generate Stereo Sound
I am trying to generate stereo sound using an Arduino UNO. Instead of using a separate DAC chip (as shown here), can I use the PWM pins on the UNO along with a low-pass filter?
Also, would I need any additional circuitry if I go this path?

To achieve stereo sound, you would need to be able to control either the volume or the phase (or preferably both) of the signals. As far as I know, neither of them are controllable by default.

Yes that would work. You need one PWM pin per Channel. That's the principle of Class D Amplifiers. Yes, you would need additional circuitry. One low pass filter per channel. The better the filter, the better the audio quality. And don't expect to achieve HiFi Quality ;-).

You can generate "stereo sound", but I don't think you'll like it.  The PWM frequency is only 490 or 980 Hz, which is going to be plainly audible unless you filter the output very severely.  So you'll only be able to produce low frequency sounds, about like what comes out of the woofer speakers in your home stereo.  In other words, nothing like music.  Might be OK for certain experiments, but nothing you'd want to listen to for pleasure.
As far as additional circuitry, you'll need to convert the DC outputs of your two low-pass filters to AC before you try to drive headphones.  This requires a big decoupling capacitor for each channel. If you are going to drive a separate amp, you might be able to skip the capacitors since most amps have them built into the inputs.

Thanks for your response. Also, I think I can change the frequency of UNO’s PWM pins.


text:
ESP32 reading analog 2.4Ghz
Is there a possibility to analog read on the 2.4Ghz band to just read how much activity is in the presence of your device? Not parsing the messages but just listening to how strong of a signal you are getting on a specific bandwidth?
All information is welcome.


text:
Arduino H-bridge for rc car
I've got an old rc car laying around, of which i would like to swap the insides, but re-use some of the parts that are already in there. The car runs 2 dc motors: one for steering, one for throttle. The dc motors are both connected to H-bridges in the original setup to make their direction switchable. This is done via 8 transistors. 4 for the throttle and 4 for the steering.
The transistors for steering are 2x S8050 (NPN) and 2x S8550 (PNP).
For throttle it uses 2x 2SD882 (NPN) and 2x 2SB772 (PNP).
I found a schematic in an online post of a arduino H-Bridge setup. It look promising, but it uses 2n4403 and 2n4401 transistors. I was wondering if I could copy the schematic, replace the Arduino 5v power source (as depicted in de schematic) with the battery voltage source of the car, and replace the transistors in the schematic with one pair of the transistors I described above (so 2x 2SD882 and 2x 2SB772 or 2x S8050 and 2x S8550) Would the arduino be able to switch the described transistors? Would the 1K ohm resistors in between the arduino and the transistors suffice?
I am planning on making this schematic twice, once for throttle and once for steering. The throttle output is max 11.5v and the steering uses around 5v. Therefore the throttle circuit would be powered from the battery voltage and the steering circuit would be powered of a 5v regulator.
Can this be done this way?

The 5 V (Steering) Version would not be a problem. But the 12V Version is a problem for the PNP transistor. You have 12 V on emmiter of the PNPs and only 5 V from the Arduino pin on the base to switch them off. That prevents the PNPs from beeing switched off and for a pin = HIGH the current flows through the PNP and NPN pair, but not trough the motor. Perhaps you could use MosFETs as a replacement. Or you use additional MosFETs  connected to the arduino with their gates and drive the 12 Volt to the bases of the NPN and PNP Transistors.

Thanks for the advice! Would a relay work for doing this as well? In my mind I'd switch the relay using 5V from the Arduino which then switches the transistor with Vbat.

It should be possible to use relays. But be sure to use flyback diodes with them. You should also check isf the relay can handle the current and voltage. A relay is a mechanical part, so it has a limitted amount of scwitch actions, it can perform. Especially with high current; the contacts burn out. Have you considered using a LM298 breakout board for the 12 V Motor?

Yes I did consider the LM298, but I don't think that it would be able to handle the amount of current that the 12v motor uses, since the LM298 has a 25W rating...?

Would the BTS7960 make a better option? (https://media.s-bol.com/mER770rAkPw9/550x309.jpg)

A 2SD882 has a 12.5 Watt rating. If you can use that NPN you could use the LM298 too. I don't know  BTS7960 and I don't know your motors, so if the ratings match - why not?

Just a comment about your diagram. The two transistors should not share an Arduino pin in that way. If the pin is pulled high the transistors saturate and your current 'shoots through' from supply straight to ground. Instead assign one Arduino pin to each transistor (using the base resistor in your diagram).

Sorry, but that is not good advice. It is much better to us one ARD pin on a NPN/PNP pair, becaus one transistor must be off and one transistor must be on for each state of the pin. That's how an H Bridge works. If you are able to switch both transistor on at the same time, the (fairly unlimited) current flows through both transistors and you'll see the famous smoke. ;-)


text:
How do I add Gyroscope, Accelerometer, Euler, and Temperature data to one Arduino board?
I have to use a BNO055 to get temperature/accelerometer/Euler/Gyroscope data into one Arduino board for a school project. I am very new to coding so I am not familiar with the commands. I have gotten my BNO055 to give me all the data individually but I am having problems getting them all compiled into one code file to upload. I have googled it but I keep getting links to upload them individually. Posted below is my latest attempt.

#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BNO055.h>
#include <utility/imumaths.h>

Adafruit_BNO055 bno = Adafruit_BNO055(55);

void setup(void)
{
  Serial.begin(9600);
  Serial.println("Orientation Sensor Test"); Serial.println("");

  /* Initialise the sensor */
  if (!bno.begin())
  {
    /* There was a problem detecting the BNO055 ... check your connections */
    Serial.print("Ooops, no BNO055 detected ... Check your wiring or I2C ADDR!");
    while (1);
  }

  delay(1000);

  bno.setExtCrystalUse(true);
}

void loop(void)
{
  /* Get a new sensor event */
  sensors_event_t event;
  bno.getEvent(&event);

  /* Display the current temperature */
  int8_t temp = bno.getTemp();

  Serial.print("Current Temperature: ");
  Serial.print(temp);
  Serial.println(" Celsius");
  Serial.print("");
}

void loop(void)
{
  /* Get a new Sensor event */
  sensors_event_t event;
  bno.getEvent(&event);

  imu::Vector<3> gyroscope = bno.getVector(Adafruit_BNO055::VECTOR_GYROSCOPE);

  /* Display the floating point data */
  Serial.print("X: ");
  Serial.print(gyroscope.x());
  Serial.print(" Y: ");
  Serial.print(gyroscope.y());
  Serial.print(" Z: ");
  Serial.print(gyroscope.z());
  Serial.println("");
  delay(100);
}

void loop(void)
{
  /* Get a new sensor event */
  sensors_event_t event;
  bno.getEvent(&event);

  imu::Vector<3> accelerometer = bno.getVector(Adafruit_BNO055::VECTOR_ACCELEROMETER);

  /* Display the floating point data */
  Serial.print("X: ");
  Serial.print(accelerometer.x());
  Serial.print(" Y: ");
  Serial.print(accelerometer.y());
  Serial.print(" Z: ");
  Serial.print(accelerometer.z());
  Serial.println("");
  delay(100);
}

void loop(void)
{
  /* Get a new sensor event */
  sensors_event_t event;
  bno.getEvent(&event);

  imu::Vector<3> euler = bno.getVector(Adafruit_BNO055::VECTOR_EULER);

  /* Display the floating point data */
  Serial.print("X: ");
  Serial.print(euler.x());
  Serial.print(" Y: ");
  Serial.print(euler.y());
  Serial.print(" Z: ");
  Serial.print(euler.z());
  Serial.println("");
  delay(100);
}

why can't you do all that inside one loop() ... you already have multiple statements inside loop(), just add more

Does the code below work? I have no compiler at hand, so I can not test it.
If you have to explain what you have done, you'll get into trouble. I don't know your teacher, but ... ;-). Seriously, that was very basic stuff. Try to find some documentation, how to program with the Arduino IDE and learn the basics. A good startpoint is https://www.arduino.cc/en/Tutorial/HomePage .
Then go on with SENSORs and Vector Maths.
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BNO055.h>
#include <utility/imumaths.h>

Adafruit_BNO055 bno = Adafruit_BNO055(55);

void setup(void)
{
  Serial.begin(9600);
  Serial.println("Orientation Sensor Test"); Serial.println("");

  /* Initialise the sensor */
  if (!bno.begin())
  {
    /* There was a problem detecting the BNO055 ... check your connections */
    Serial.print("Ooops, no BNO055 detected ... Check your wiring or I2C ADDR!");
    while (1);
  }

  delay(1000);

  bno.setExtCrystalUse(true);
}

void loop(void)
{
  /* Get a new sensor event */
  sensors_event_t event;
  bno.getEvent(&event);

  /* Display the current temperature */
  int8_t temp = bno.getTemp();

  Serial.print("Current Temperature: ");
  Serial.print(temp);
  Serial.println(" Celsius");
  Serial.print("");

  imu::Vector<3> gyroscope = bno.getVector(Adafruit_BNO055::VECTOR_GYROSCOPE);

  /* Display the floating point data */
  Serial.print("X: ");
  Serial.print(gyroscope.x());
  Serial.print(" Y: ");
  Serial.print(gyroscope.y());
  Serial.print(" Z: ");
  Serial.print(gyroscope.z());
  Serial.println("");
  delay(100);

  imu::Vector<3> accelerometer = bno.getVector(Adafruit_BNO055::VECTOR_ACCELEROMETER);

  /* Display the floating point data */
  Serial.print("X: ");
  Serial.print(accelerometer.x());
  Serial.print(" Y: ");
  Serial.print(accelerometer.y());
  Serial.print(" Z: ");
  Serial.print(accelerometer.z());
  Serial.println("");
  delay(100);

  imu::Vector<3> euler = bno.getVector(Adafruit_BNO055::VECTOR_EULER);

  /* Display the floating point data */
  Serial.print("X: ");
  Serial.print(euler.x());
  Serial.print(" Y: ");
  Serial.print(euler.y());
  Serial.print(" Z: ");
  Serial.print(euler.z());
  Serial.println("");
  delay(100);
}

Thank you so much. My teacher only told us what to do, since classes are online he has been pretty lazy, he did not give us any references to look at so thank you for the link also. Sorry for the basic question lol im a petroleum engineering student so I am way out of my comfort zone with coding. And your code worked. I could not thank you enough for the help.

You're welcome. Generally, I do not handle the homework for others. But you were honest and told us about the background. I also know from students in my neighbourhood how studying works these days. I'm seriously concerned about that. I'm from Germany - guessing by your name I would expect you are an irish man, so it seams, other countries have the same problems. Knowledge and Education are such precious assets, we should not waste them. I'm glad, I could help you.


text:
Moving and Stopping Stepping motor without using delay
I'm using a stepper motor with an external limit switch (so when power is on the motor will know where to start from) with an L6470 motor drive.
What I want to do here is

when power is ON → turn Clock Wise (CW) until it hits external Limit Switch
Once the limit switch is ON → Turn Anti-Clock Wise (CCW) for 550 mil seconds
Rest for 100 mil seconds
Turn Clock Wise (CW) for 200 mil seconds
Rest for 100 mil seconds
Turn Anti-Clock Wise (CCW) for 200 mil seconds
....loop from 3 to 6

My current code is using "counter". This is because I can't use "delay" in this code since it interrupts the limit switch activation code.
I've only written easy codes and don't know how to make it rest without using "delay".
Please help....
/***********************

回転

************************/
#include <Arduino.h>
#include <SPI.h>

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

long max_speed = 7000;// 70000 固定

long int dd = 200;// 微増・微減の量 400
int dt = 10; // 微増・微減にかける時間　ミリ秒

int t_interval = 10;// (休止する時間 みり秒）
int t_hold = 170; //　最高速を維持する時間　ミリ秒）

int steps;

#define PIN_SPI_MOSI 11
#define PIN_SPI_MISO 12
#define PIN_SPI_SCK 13
#define PIN_SPI_SS 10

#define PIN_L6470_SS PIN_SPI_SS

void L6470_write(unsigned char data);
void L6470_init(void);
void L6470_run(long speed);

long speed = 1000;
long int n_dir = 0 ;
long offTime;

int c_step = max_speed / dd;

const int limit_sw = 7;
bool switchState = false;
int counter = 0;
int milsec = 0;
bool speedSwitch = false;

void setup()
{
 pinMode(PIN_SPI_MOSI, OUTPUT);
 pinMode(PIN_SPI_MISO, INPUT);
 pinMode(PIN_SPI_SCK, OUTPUT);
 pinMode(PIN_L6470_SS, OUTPUT);

 pinMode(limit_sw, INPUT_PULLUP );

 digitalWrite(PIN_L6470_SS, HIGH);

 SPI.begin();

 Serial.begin(9600);

 L6470_init();

 Serial.println("Start...");

void loop()
{

int value = digitalRead(limit_sw);

if(value == 0){
  counter ++;
  if(counter > 50){//もともと３
    switchState = true;
    counter = 50;
  }
}
if (switchState == true){
  milsec++;
  Serial.println(milsec);
  if(milsec > 550){
    speedSwitch = !speedSwitch;
    milsec = 0;
  }

  int speed;
  if(speedSwitch == true){
    //Serial.println("speedSwitch : true");
    speed = 200;

  }

  else{
    //Serial.println("speedSwitch : false");
    speed = -200;
  }

}

else{

   L6470_run( 100 );//速度

}
}

void L6470_write(unsigned char data)
{
 // ~SSイネーブル。
 digitalWrite(PIN_L6470_SS, LOW);
 // SPI転送。
 SPI.transfer(data);
 // ~SSディスエーブル。
 digitalWrite(PIN_L6470_SS, HIGH);
}

void L6470_init()
{
 // MAX_SPEED設定。
 /// レジスタアドレス。
 L6470_write(0x07);
 // 最大回転スピード値(10bit)　００２０

 L6470_write(0x00);
 L6470_write(0x90);

 // KVAL_HOLD設定。
 /// レジスタアドレス。
 L6470_write(0x09);
 // モータ停止中の電圧設定(8bit)
 L6470_write(0xFF);

 // KVAL_RUN設定。
 /// レジスタアドレス。
 L6470_write(0x0A);
 // モータ定速回転中の電圧設定(8bit)
 //L6470_write(0xFF);
 L6470_write(0x64);

 // KVAL_ACC設定。
 /// レジスタアドレス。
 L6470_write(0x0B);
 // モータ加速中の電圧設定(8bit)
 L6470_write(0xFF);

 // KVAL_DEC設定。
 /// レジスタアドレス。
 L6470_write(0x0C);
 // モータ減速中の電圧設定(8bit)
 L6470_write(0xFF);

 // OCD_TH設定。
 /// レジスタアドレス。
 L6470_write(0x13);
 // オーバーカレントスレッショルド設定(4bit)
 L6470_write(0x0F);

 // STALL_TH設定。
 /// レジスタアドレス。
 L6470_write(0x14);
 // ストール電流スレッショルド設定(4bit)
 L6470_write(0x7F);
}

void L6470_run(long speed)
{
 unsigned short dir;
 unsigned long spd;
 unsigned char spd_h;
 unsigned char spd_m;
 unsigned char spd_l;

//spd = speed;

 // 方向検出。

 if (speed < 0)
 {
  dir = 0x50;
  spd = -1 * speed;
 }
 else
 {
  dir = 0x51;
  spd = speed;
 }

 // 送信バイトデータ生成。
 spd_h = (unsigned char)((0x0F0000 & spd) >> 16);
 spd_m = (unsigned char)((0x00FF00 & spd) >> 8);
 spd_l = (unsigned char)(0x00FF & spd);

 // コマンド（レジスタアドレス）送信。
 L6470_write(dir);
 // データ送信。
 L6470_write(spd_h);
 L6470_write(spd_m);
 L6470_write(spd_l);

  Serial.print( " current spd = ");
  Serial.println( spd );
}


text:
What terminologies and concepts describe the codes that follow a format of Text1.Text2()?
I'm just really curious because some codes really follow a format like this. Examples include serial.begin(), serial.println() and when I used servomotors the left part was the name of the servomotor, which I declared. I want to know what concept does the code with a format of Text1.Text2() refer to? What do you call Text1 and Text2? Are there official or commonly used terminologies for the concepts and parts such as "variable", "statement", "code"?
To add to my understanding, it appears that Text1 refers to an object and that Text2 has the concept of "function" where it performs something related to the object. Though I would think that another terminology would be possessed by Text2 other than function to distinguish it from a function since it is required to be written in the format I mentioned, which next to the object with a period separating them and no spaces at all.

the names differ amongst different programming  languages ... your question has nothing to do with the Arduino, so it is off topic here .... look at details about a programming language of interest ... see what the names are

https://www.w3schools.com/cpp/cpp_classes.asp

@jsotola: It's not mainly the names that differ, but their semantic meaning. What Text1.Text2() could mean differs greatly by language, even if this may be a syntactically valid statement in many languages.

Text1 is an instance of some class xxx; xxx::Text2() is it's method function.

As @KIIV wrote, the overall concept is the class concept. A class is the build description of an object with its own member functions and member variables. From a class you can declare instances as variables in your code. Thats, what Text1 is here: An instance of a class. Text2() in turn is a member function of that class, which can act upon the variables of that particular instance. You can google tutorials about C++ classes to find out more. Note, that in C/C++ classes and structs are very similar. So you use a similar syntax to refer to member variables of a struct instance.

Class and method are probably the answers I need. Thanks! It's just so hard to search with Google if you don't have the correct keywords to obtain what idea you want clarified.

'Text1' is usually an object. Object is an instance of a class. https://en.wikipedia.org/wiki/Object-oriented_programming#Objects_and_classesg

The over-arching concept is Object Oriented Programming (OOP).
The terms I was taught at University - taking Serial.println() as an example:

Serial is an instance of a class (in this case HardwareSerial), sometimes called an object.
println() (a function in a class) is a method of a class.
A "variable" in a class is called a property of a class.

A commented code example:

class Foo { // This is the *class*

    public: // These symbols are accessible from outside the class

        int bar; // This is a public property

        void baz() { // This is a public method
        }

    private: // These symbols are only available from inside the class

       int meep; // This is a private property

       void moop() { // this is a private method
       }
};

Foo bar; // Instantiate an instance of the Foo class and call it bar.


text:
Fast PWM with Arduino, the inputs outputs don't work
Hello to the community!
I am using ATTINY85 and I am programming it through the AVRISP using an Arduino UNO.
This is the code I am using :
#include <avr/io.h>
#include <avr/interrupt.h>

void setup() {
    PORTB = 0;        //Reset values on port B

    // After setting up the timer counter,
    // set the direction of the ports to output
    DDRB |= (1<<PB1) | (1<<PB0) | (1<<PB3); // PB0, PB1 and PB3

    // PLLCSR - PLL control and status register:
    // PLL is a clock multiplier
    //      - multiplies system 8 MHz by 8 to 64 MHz
    // PLL is enabled when:PLLE bit is enabled,
    // CKSEL fuse is programmed to 0001.  This clock is
    //   switched off in sleep modes!
    PLLCSR |= (1<<PLLE);    // PLL enable

    // Wait until the PLOCK bit is enabled
    // before allowing the PCK to be enabled
    //WaitForPLOCK();
    //unsigned int i = 0;

    while ((PLLCSR & (1<<PLOCK)) == 0x00)
    {
        // Do nothing until plock bit is set
    }

    // Enable asynchronous mode, sets PWM clock source
    PLLCSR |= (1<<PCKE);

    TCCR1 = (1<<CTC1)    | // Enable PWM
            (1<<PWM1A)   | // Set source to pck
            (0<<(CS13))  |
            (0<<(CS12))  |
            (1<<(CS11))  |
            (1<<(CS10))  | // Clear the pin when match with ocr1x
            (1<<COM1A1);
    GTCCR = (1<<PWM1B) | (1<<COM1B1);

    // Set PWM TOP value - counter will count and reset
    //  after reaching this value
    //           OCR1C
    // 100 kHz   159
    // 80 kHz    199
    OCR1C = 199;

    // Enable Timer1 OVF interrupt
    TIMSK = (1<<OCIE1A) | (1<<TOIE1);

    sei();

    OCR1A = 190;  //chaning th FR
}

void loop() {
    PORTB |= (1 << PB3);
    delay(500);
    PORTB &= ~(1 << PB3);
    delay(500);
}

the problem is that when I use the PWM my rest of the outputs do not work . Any idea why is this happening?
I am using the ATTINY CORE library from Spence Konde.

This line:
TIMSK = (1<<OCIE1A) | (1<<TOIE1);

enables a couple of interrupts generated by Timer 1. Whenever you
enable an interrupt source, you should make sure that the matching ISR
has been defined. Otherwise, the interrupt request is routed to
__bad_interrupt(), which by default jumps to the reset vector, thus
resetting your program.

Amazing!! Thank you! That worked out!


text:
How should I decide the cut-off frequency for my low-pass filter?
I'm trying to generate some basic thumping stereo sound using Arduino's PWM pins along with low-pass filters.
This is the frequency spectrum for the sound I want to play using Arduino UNO's PWM pins:

Based on this, I think (from what I understand) the cut-off frequency for the low-pass filter should be around 8900Hz. But, wouldn't the PWM function operate at a much higher frequency to generate the same wave? If that's how it'll be, how should I decide the cut-off frequency for my low-pass filter?
I understand that the fastest frequency one can get for 8-bit PWM on an UNO is 62.5 kHz. So, I might not be able to generate this wave using the UNO itself. Unfortunately, I won’t be able to use another microcontroller for this project. However, what I can do to solve this issue is - generate a different sound wave of lower frequency. If someone can help me with finding out by how much will the frequency of the wave increase if I use PWM to generate it, I’ll be able to generate an appropriate wave.

Yes, you would need a PWM frequency much higher than the frequency you want, but the PWM frequency of the UNO is fixed at 490Hz (see https://www.arduino.cc/reference/en/language/functions/analog-io/analogwrite/). Doesn't look like that's going to work.

@PMF I think it is possible to increase the default frequency. Found some tutorials online, but here’s a similar question on this forum: https://arduino.stackexchange.com/questions/25609/set-pwm-frequency-to-25-khz

If you have an Uno or some similar AVR-based board, the fastest frequency you can get for 8-bit PWM is 62.5 kHz. You could go faster at the expense of resolution.

You'll probably want a Teensy for this.

@towe Unfortunately, I won’t be able to use a Teensy for this project. However, what I can do to solve this issue is- generate a different sound wave. If someone can help me with finding out by how much will the frequency of the wave increase if I use PWM to generate it, I’ll be able to generate an appropriate wave.

That looks like the spectrum of an 8-bit sound that is playing low bass notes only.  Most everything above that looks like noise floor.  (You can only get about 6 dB range per bit of resolution, so 8 bits gives about 48 dB max.)  If this is the case, you definitely don't want to reproduce the upper frequencies.  If you want to stick to your original PWM scheme, use pins 5 or 6 because they use 980 Hz PWM instead of 490.  I suggest you determine the filter by trial and error, since it comes down to how much PWM carrier you can tolerate.  You can make a simple RC filter using the formula F = 1 / (2 * pi * R * C) where F is the cutoff frequency in Hz, R is ohms, and C is farads (that's 10^6 microfarads per farad).  This type of simple filter will have a very soft cutoff frequency, about 6 dB per octave, so if you set it for 123 Hz (3 octaves below 980 Hz) the 980 Hz PWM will be reduced by 18 dB.  The R connects to the PWM pin, and the C goes from the other end of R to ground, as does the signal output.  The formula assumes that there is no output load, so you should connect an amplifier there.  If you are like most folks, you probably have fewer capacitor values on hand than resistor values, so pick the C value first.  Let's say it's 1 uFd.  Then if you use R=1K the cutoff will be 159 Hz.  Change R while listening to the output


text:
Using millis() instead of delay() when playing a melody
I want to make my Arduino to play several simple melodies, and also be able to skip a melody by pressing a button and go on with the next song. therefore I cannot use delay() because the code should constantly check if a button is pressed. So I wanted to use millis(), but dont't know how to implement it.
this is how song code looks like with delay():
#define NOTE_B0  31
#define NOTE_C1  33
#define NOTE_CS1 35
//etc...

int tempo=144;

// change this to whichever pin you want to use
int buzzer = 11;

int melody[] = {

  //Based on the arrangement at https://www.flutetunes.com/tunes.php?id=192

  NOTE_E5, 4,  NOTE_B4,8,  NOTE_C5,8,  NOTE_D5,4,  NOTE_C5,8,  NOTE_B4,8,
  // etc...

};

// sizeof gives the number of bytes, each int value is composed of two bytes (16 bits)
// there are two values per note (pitch and duration), so for each note there are four bytes
int notes=sizeof(melody)/sizeof(melody[0])/2;

// this calculates the duration of a whole note in ms (60s/tempo)*4 beats
int wholenote = (60000 * 4) / tempo;

int divider = 0, noteDuration = 0;

void setup() {
  // iterate over the notes of the melody.
  // Remember, the array is twice the number of notes (notes + durations)
  for (int thisNote = 0; thisNote < notes * 2; thisNote = thisNote + 2) {

    // calculates the duration of each note
    divider = melody[thisNote + 1];
    if (divider > 0) {
      // regular note, just proceed
      noteDuration = (wholenote) / divider;
    } else if (divider < 0) {
      // dotted notes are represented with negative durations!!
      noteDuration = (wholenote) / abs(divider);
      noteDuration *= 1.5; // increases the duration in half for dotted notes
    }

    // we only play the note for 90% of the duration, leaving 10% as a pause
    tone(buzzer, melody[thisNote], noteDuration*0.9);

    // Wait for the specief duration before playing the next note.
    delay(noteDuration);

    // stop the waveform generation before the next note.
    noTone(buzzer);
  }
}

I found this code on internet but I don't know how to implement this in above code. when I try to, I get some kind of cursed sound.
unsigned long previousMillis = 0;
boolean outputTone = false;

if (millis() - previousMillis >= noteDuration) {
    previousMillis = millis();
    if (outputTone) {
        noTone(buzzer);
        outputTone==false;
    } else {
        tone(buzzer, melody[thisNote], noteDuration*0.9);
        outputTone==true;
    }
}

edit1: I tried this:
    unsigned long previousMillis = millis();
    int thisNote = 0;

    while (thisNote < notes * 2) {

        // calculates the duration of each note
        divider = lied1[thisNote + 1];
        if (divider > 0) {
            // regular note, just proceed
            noteDuration = (wholenote) / divider;
        } else if (divider < 0) {
            // dotted notes are represented with negative durations!!
            noteDuration = (wholenote) / abs(divider);
            noteDuration *= 1.5; // increases the duration in half for dotted notes
        }

        // play the note
        tone(buzzer, melody[thisNote]);

        check();//check if button is pressed, and if so, changes number to 2
        if (number ==2){
            thisNote=notes*2;
        }
        if ((millis() - previousMillis) >= noteDuration){
           thisNote = thisNote + 2;
           // stop the waveform generation before the next note.
           noTone(buzzer);
        }

     }

but it doesn't work, and I don't really understand why
edit2: I changed something, this is probably the closest I have been to a working melody without "delay()". But it is extremely slow.
    boolean outputTone = false;
    unsigned long previousMillis = millis();
    int thisNote = 0;

    while (thisNote < notes * 2) {

        // calculates the duration of each note
        divider = lied1[thisNote + 1];
        if (divider > 0) {
            // regular note, just proceed
            noteDuration = (wholenote) / divider;
        } else if (divider < 0) {
            // dotted notes are represented with negative durations!!
            noteDuration = (wholenote) / abs(divider);
            noteDuration *= 1.5; // increases the duration in half for dotted notes
        }

        if (millis() - previousMillis >= noteDuration) {
            previousMillis = millis();
            if (outputTone) {
                noTone(buzzer);
                outputTone==false;
            } else {
                tone(buzzer, melody[thisNote], noteDuration*0.9);
                outputTone==true;
                thisNote = thisNote + 2;
            }
        }

        check(); //checks if button is pressed, and if so, changes number to 2.
        if (number ==2){
            thisNote=notes*2;
        }
     }

In essence you will need to break your for loop open and use a global variable for thisNote, incrementing it each loop (with the millis example so that proper timing is still adhered to).
This isn't the only approach to this problem. Your existing code could check for the button press within the for loop and escape the for loop when pressed.

thanks for your comment! I don't fully understood what you meant, but I tried something (I edited my post). I changed my for loop in a while loop. but it still does not work.

I don't quite understand the code snippets, that you added to your question afterwards (they are partly incomplete). But I will propose my own solution to the problem.
A melody is a list of notes and pauses. Each note has a pitch and a duration. A pause has only a duration. We can now define a struct for holding a note:
struct Note {
    unsigned int pitch;
    unsigned int duration;
};

Since a pause does not have a pitch, we can use our struct for a note by setting the pitch to an invalid value (for example zero). For building a melody we are now  defining an array of Notes. But since we want multiple melodies, so that we can switch between them, we are using a 2 dimensional array for defining all melodies in one array:
#define NR_MELODIES  2
#define MELODY_LENGTH 8
Note melody[NR_MELODIES][MELODY_LENGTH] = {
    { // melody 0
        {0      , 4}, //pause
        {NOTE_E5, 4},
        {NOTE_B4, 8},
        {NOTE_C5, 8},
        {NOTE_D5, 4},
        {NOTE_C5, 8},
        {0      , 8}, // pause
        {NOTE_B4, 8}
    },
    { // melody 1
        {0      , 4}, //pause
        {NOTE_B4, 8},
        {NOTE_C5, 8},
        {NOTE_D5, 8},
        {NOTE_C5, 4},
        {NOTE_B4, 8},
        {0      , 8}, // pause
        {NOTE_E5, 4}
    }
};

Here I used the divider (part of the whole note), just like you did in your code. A 4 means a quarter note, 8 an eight note. For preventing loosing the first note, I inserted a quarter pause at the start.
We also need a variable to hold the current position in our melody, one for the current melody and a timestamp variable for the timestamp of the last played note:
unsigned int current_note = 0;
unsigned int current_melody = 0;
unsigned long last_note_timestamp = 0;

Now in void loop() we check for our timestamp and the duration of the current note. If the current note should end, we end it, increment to the next note and start playing it:
if(millis() - last_note_timestamp > wholenote/melody[current_melody][current_note].duration){
    last_note_timestamp += wholenote/melody[current_melody][current_note].duration; // increment timestamp to start of next note
    noTone(buzzer); // stop current note
    current_note++; // increment to next note
    if(melody[current_melody][current_note].pitch){ // next note is not a pause
        tone(buzzer, melody[current_melody][current_note].pitch, wholenote/melody[current_melody][current_note].duration); // start note
    }
}

And after the if statement we can add an if statement for checking the melody change button. You didn't include the button check code in your question, so I will just use a placeholder function here.
if(change_melody_pressed()){
    // incrementing current melody and wrap around, if we reached last melody
    current_melody = (current_melody + 1) % NR_MELODIES;
    // reset current note to play melody from start
    current_note = 0;
}

Now we still need to think about, what happens, when a melody finishes. 3 possibilities:

We could restart the current melody: We need to check for the last note in a melody, and then reset current_note:
  if(current_melody >= MELODY_LENGTH ){
      current_note = 0;
  }

We can increment to the next melody: Like above, but we add the melody incrementing line in the if statement:
  current_melody = (current_melody + 1) % NR_MELODIES;

We can stop playing: Here I would use the above if statement and set current_note to -1. Then we need to check in our first if statement, if current_note is not -1:
  if(current_note != -1 && millis() - last_note_timestamp > wholenote/melody[current_melody][current_note].duration)

Note: I have not tested the above code, but I compiled it to try finding syntax errors.


text:
Adding new programmer to Arduino IDE
I want to use the Arduino IDE using a raspberry pi with raspbian OS because it's the only way I can read a Digispark usb (I don't have 2.0 usb ports in my laptop so I can't read the usb with it).
I installed arduino IDE 1.8.13 so I can add the Digistump package. The problem I got is that when I try to add the drivers from the link http://digistump.com/package_digistump_index.json, it returns Tool micronucleus is not available for your operating system..
I donwloaded micronucleus using
git clone https://github.com/micronucleus/micronucleus

and installed it. Now I have it but I don't know how the arduino IDE could detect it. Could someone help me on how to make the arduino IDE understand I have it (micronucleus) installed?

The question could be answered directly, but it's probably easier for you to just insert a USB 2.0 HUB in the path to your device rather than messing around with the Pi and trying to fix the board support to work on the Pi.   Also, my understanding is that micronucleus can work on USB 3.0 if you get the correct version installed.

Which is the correct version ? I’m new in this stuff, so any answer that could help is really useful :-)

v2.01 (or newer), I think.  Although, the comment seems to suggest it should not have fixed the problems I've seen it fix.  So, dunno.  Sometime in the next week I'll have one of these myself, which is ironic, because I don't recommend them.

@iam_agf, I found this when looking up "laucher", in the process of doing pretty much exactly what's written there.  I compiled micronucleus under Raspbian, but that's about as far as I went.  Kind of looks like they got it working, so I'm not sure what the point in me continuing with it would be.


text:
What is the difference when an arduino has been unplugged vs when a serial port connection was closed?
Using python code for a serial port connection to an arduino, it sends a value to the arduino, which then starts printing values to serial. The python code will print the value on the first or second run (if run soon enough after), but after that it won't read what's from Serial.println again. To get it to read again (whether I wait some time or not, like for the while loop to finish), the arduino has to be unplugged and plugged in again, why is that different than the serial port connection being closed by python? Here is the arduino code used,
int measured;
int counter = 0;
int maxnum = 10;

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

void loop()
{
  if(Serial.available() > 0)
  {
    while(counter < maxnum)
    {

        Serial.println("V");
        counter++;
        delay(100);

    }
  }
}

I know the value sent from python can be read because I added in code that reads from serial after checking if it's available and changed an output pin value, which works, even if the serial println is not read.
Edit: Since the answer is there shouldn't be a significant difference and the arduino script should be reset if the serial port was closed, the issue should be with the python code.

We cannot know, if your python code also has a problem. But your Arduino code will send the series of "V" only once.
You are using this while loop:
while(counter < maxnum)

in there you are incrementing the variable counter. But after you left the while loop, you are never resetting counter to zero. So the next time, counter is still equal to maxnum. Thus the while loop will not run again. To solve that, insert
counter = 0;

directly after your while loop. Though, for such loops its normally easier to just use a for loop.

Also you might have a second problem. Currently the code waits for Serial data to be received. When something is received, the code will enter the
if(Serial.available() > 0)

statement. But this will stay true, unless you are actually reading the data. Currently the code inside the if statement will be executed on every loop() interation forever. So if you are applying the above fix to the first problem, the code will send "V" forever after you send the first byte to the Arduino. To actually only react to data being received, you need to read the data from the buffer - even if you are throwing the data away:
Serial.read();

What is the difference when an arduino has been unplugged vs when a serial port connection was closed?

For the Arduino itself? Nearly none. Reopening the serial connection will cause the Arduino to reset. The code then starts again from its beginning. Thats also what happens, when you power cycle (replugging) the Arduino. I think there are some little details, where both differ, but that certainly is not the problem here.
For the computer, replugging means, that the USB device (the USB-to-Serial chip on the Arduino to be precise) gets disconnected and again connected. That can lead to the OS allocating a different com-port/device-file for it, than before. Though that doesn't directly do something with the Arduino code (apart from the mentioned power cycle with reset).
For resetting (preserved from comment of OP):

I found that by setting DTR to 0 then 1, then 0 again, right before closing the port, the arduino resets.

Ok, yes I had taken out some code to make the simplest example, but in either case, it should read 'V' at least once when starting. When I use pyserial it would read again after rerunning the script, but with pyqt5 it would not read again. So maybe it's an issue with certain python code not closing the serial port properly, if unplugging and closing the serial port should give the same results. Here is the pyqt5 python version that won't read again.

Though yes, when I put if(Serial.available() > 0)   {     int counter = 0; instead of having the counter initialized at the start, it does read each time. So again, it sounds like the python code was not resetting the arduino code with a new serial port connection.

I'm no expert in pyqt5 serial, but wouldn't that code just exit, when it received one (or a few) line? And the program just exits without reopening the serial port. So when exactly did you think, that the port should be reopened?

It would be reopened when I run the script again. Yes it just reads one line, but if have the python code read 10 lines like the arduino prints, it still doesn't seem to reset the arduino code when restarting the script. I was just trying to have the simplest script here.

Mhh, as written above, we are no experts in pyqt5 serial. The Arduino will reset on signals on the DTR or RTS lines (reference question). Maybe the pyqt5 implementation does not do this by default. You can look into the options of pyqt5 serial. For us that is out of scope. If you need help with that, you can try asking at stackoverflow. That might get you better results, than here.

Yes I have altered the stack overflow question to ask about how pyqt5 opens and closes. Maybe it is an issue with that, pyqt5 has options to set DTR and RTS. Thanks.

Do you know if this would be related to why the python code would sometimes receive and print out a bytes object b'V' instead of a string object V? This could be for another question and could be an issue with the python code again though.

Thats totally on the python side. The serial interface doesn't know the difference between the string V and the byte object b'V'. I would consider it normal, if the python code gave me a byte object as serial data (since serial data isn't necessarily string data; could also be real binary)

I found that by setting DTR to 0 then 1, then 0 again, right before closing the port, the arduino resets.

@user14094230 Great! I have preserved that at the end of my answer, since the comments are temporary and this might help others with the same problem.


text:
Side by side two TFT LCDs 1.8'' with ST7735 driver but one acts differently
Hardware setup:

Custom PCB with ATMega 2560
Working Batch: TFT LCDs 1.8'' with ST7735 driver (Chinese version)
Bad Batch: TFT LCDs 1.8'' with ST7735 driver (Chinese version)

Library:
From Adafruit, latest version (1.7.0)
I've been using those LCDs for years. But, the LCDs I bought lately are not working as they should be.
They look completely identical from outside. I've bought from several different sellers from China just in case. All of them have the same behavior.
I therefore decided to find a software solution rather than trying out all LCDs in Chinese market.
Whatever variant of ST7735s I have (sellers claim they are just ST7735 nothing else), I need to adapt it to my software accordingly.
In order to keep the trial efforts efficient, I only test on the examples given by Adafruit until I proof it works. I share the outcome of the good and bad LCDs for your comparison below.
Any input greatly appreciated.

EDIT: A library had been sent by a seller. But, It doesn't look like it is 100% corresponding to ST7735. For example, since @Majenko asked, I add the initialization code from the library;
void Lcd_Init(void)
{

//调用一次这些函数，免得编译的时候提示警告
    LCD_CS =1;
    if(LCD_CS==0)
    {
       LCD_WR_REG_DATA(0,0);
       LCD_ShowString(0,0," ");
       LCD_ShowNum(0,0,0,0);
       LCD_Show2Num(0,0,0,0);
       LCD_DrawPoint_big(0,0);
       LCD_DrawRectangle(0,0,0,0);
       Draw_Circle(0,0,0);
     }

    LCD_REST=1;
    delayms(5);
    LCD_REST=0;
    delayms(5);
    LCD_REST=1;
    LCD_CS=1;
    delayms(5);
    LCD_CS =0;  //打开片选使能

        LCD_WR_REG(0x11); //Sleep out
    delayms(120); //Delay 120ms
    //------------------------------------ST7735S Frame Rate-----------------------------------------//
    LCD_WR_REG(0xB1);
    LCD_WR_DATA8(0x05);
    LCD_WR_DATA8(0x3C);
    LCD_WR_DATA8(0x3C);
    LCD_WR_REG(0xB2);
    LCD_WR_DATA8(0x05);
    LCD_WR_DATA8(0x3C);
    LCD_WR_DATA8(0x3C);
    LCD_WR_REG(0xB3);
    LCD_WR_DATA8(0x05);
    LCD_WR_DATA8(0x3C);
    LCD_WR_DATA8(0x3C);
    LCD_WR_DATA8(0x05);
    LCD_WR_DATA8(0x3C);
    LCD_WR_DATA8(0x3C);
    //------------------------------------End ST7735S Frame Rate-----------------------------------------//
    LCD_WR_REG(0xB4); //Dot inversion
    LCD_WR_DATA8(0x03);
    LCD_WR_REG(0xC0);
    LCD_WR_DATA8(0x28);
    LCD_WR_DATA8(0x08);
    LCD_WR_DATA8(0x04);
    LCD_WR_REG(0xC1);
    LCD_WR_DATA8(0XC0);
    LCD_WR_REG(0xC2);
    LCD_WR_DATA8(0x0D);
    LCD_WR_DATA8(0x00);
    LCD_WR_REG(0xC3);
    LCD_WR_DATA8(0x8D);
    LCD_WR_DATA8(0x2A);
    LCD_WR_REG(0xC4);
    LCD_WR_DATA8(0x8D);
    LCD_WR_DATA8(0xEE);
    //---------------------------------End ST7735S Power Sequence-------------------------------------//
    LCD_WR_REG(0xC5); //VCOM
    LCD_WR_DATA8(0x1A);
    LCD_WR_REG(0x36); //MX, MY, RGB mode
    LCD_WR_DATA8(0xC0);
    //------------------------------------ST7735S Gamma Sequence-----------------------------------------//
    LCD_WR_REG(0xE0);
    LCD_WR_DATA8(0x04);
    LCD_WR_DATA8(0x22);
    LCD_WR_DATA8(0x07);
    LCD_WR_DATA8(0x0A);
    LCD_WR_DATA8(0x2E);
    LCD_WR_DATA8(0x30);
    LCD_WR_DATA8(0x25);
    LCD_WR_DATA8(0x2A);
    LCD_WR_DATA8(0x28);
    LCD_WR_DATA8(0x26);
    LCD_WR_DATA8(0x2E);
    LCD_WR_DATA8(0x3A);
    LCD_WR_DATA8(0x00);
    LCD_WR_DATA8(0x01);
    LCD_WR_DATA8(0x03);
    LCD_WR_DATA8(0x13);
    LCD_WR_REG(0xE1);
    LCD_WR_DATA8(0x04);
    LCD_WR_DATA8(0x16);
    LCD_WR_DATA8(0x06);
    LCD_WR_DATA8(0x0D);
    LCD_WR_DATA8(0x2D);
    LCD_WR_DATA8(0x26);
    LCD_WR_DATA8(0x23);
    LCD_WR_DATA8(0x27);
    LCD_WR_DATA8(0x27);
    LCD_WR_DATA8(0x25);
    LCD_WR_DATA8(0x2D);
    LCD_WR_DATA8(0x3B);
    LCD_WR_DATA8(0x00);
    LCD_WR_DATA8(0x01);
    LCD_WR_DATA8(0x04);
    LCD_WR_DATA8(0x13);
    //------------------------------------End ST7735S Gamma Sequence-----------------------------------------//
    LCD_WR_REG(0x3A); //65k mode
    LCD_WR_DATA8(0x05);
    LCD_WR_REG(0x29); //Display on

}

They probably have different panels with different drive requirements.

@Majenko, yes, indeed. But which one? Million-dollar question. Sellers send me datasheet, drivers, etc. All point to ST7735.

Of they have sent you code you should compare the startup register settings against your existing code.

@Majenko, I did the comparison as you asked. There are similarities but differences as well. I also roughly compared to some other driver (ILI9341). I still couldn't recognize the driver. Maybe you may know. I edited my post and added that INIT code.  All library is a bit long so I didn't add here. If necessary I can. However, as you know that you can't trust the seller if they ever sent me the correct driver or they ever aware of what they sell.

The problem is that a TFT is made up of two parts: the controller chip, and the panel. The chip has to be configured by software to drive the panel in the right way. You can have the same chip on many different panels, and a library for one won't work right with another. I can check over the init code later on.

I think I see the difference. You have a library for the ST7735, but these new ones are in fact the ST7735S - a very different (though confusingly named) chip that needs a different library. Adafruit don't appear to have one, so you will have to find one by someone else.

@Majenko, I think so too. Either I will try to find one if exists (probably) or I will give a chance to the one given by the seller and try to convert it into Ardunio library. Thanks for the heads-up.

It's the init routine that needs replacing in the Adafruit library. It should be easy enough to port.

I replaced the INIT as per the code I mentioned in my post. But all I get a white background.

I've just ordered one on eBay from China. It'll take a few weeks to arrive....

As a backup plan, I've asked my Chinese PCB manufacturer to look for ST7735R versions locally. So, at least I might save the day while I am still working on an S version. I guess, you want to also make a library for everyone's sake, that would be great. I searched many resource centers like github. I am sure somebody already made one but many of them claim their library is for ST7735S but if you look at closely, it is still calling initR from Adafruit library. I guess, not many people aware of that S variant. Since that LCDs have no MISO (no read), you can't query the version of the LCD :(

I had asked my PCB manufacturer for looking bare display without back-plane a few days ago and told them that If they can find one and it works OK, I can design a back-plane for it and you make. Guess what, they found one. But strange thing is that the one they bought is -S version (claimed so) and they tested with my PBC and it worked. This is crazy. I am puzzled, I don't know what to say.

My supplier only does the -S version now (https://www.buydisplay.com/tft-display/tft-display-panel?cotroller_ic=883) so I guess the old non-S one has been discontinued. The -S variant is more capable anyway.

My TFT has just arrived. I'm going to spend today setting it up and getting it going. I'll report back later.

Ok, this is strange. Mine works straight out of the box. The PCB is a little different to yours, but it's supposedly an St7735S chip. Like yours it's a "green tab" variant panel, but I don't tell it to use the green tab init, just the default black tab, which works fine (the green tab init just adds an offset to the display).

You are lucky then. I didn't take my chance this time and I made a back-plane design and it is going to be manufactured next week for bare LCD. I purchased the bare LCDs. My fab will assemble them. At least that way I could also add some TVS for the SPI lines. Last time, during EMC tests the LCD was failed.

However, you said that Adafruit has not the ST7735S library. Have you made one yourself? If it is so, would you like to share for the Arduino community somewhere reachable?

No, it's just the stock adafruit library - when I started experimenting and looking at the examples I saw they have the .initR() function for selecting the variant: https://github.com/adafruit/Adafruit-ST7735-Library/blob/master/examples/graphicstest/graphicstest.ino#L87


text:
Increase or decrease const byte value inside the code with a push button
I'm kind of new in the Arduino world. I decided to make a self learning project with an Arduino where it controls a conveyor that simply moves from right to left and back again. There is a start and stop button. On each end of the conveyor are inductive sensors to stop the motor when it reaches the end position. After a delay, the conveyer starts again the opposite direction. Inside the code I have a cycle counter that stops the conveyer after a certain number of cycles.
Now my question is, how could I change the value of the cycle counter using two push buttons. One to increase the other to decrease.
If there is somebody who could help I would appreciate.
Thanks already
const byte sensorLinksEnd  =  2;
const byte sensorRechtsEnd =  3;
const byte startPin        =  4;
const byte stopPin         =  5;
const byte relaisLinks     =  6;
const byte relaisRechts    =  7;

enum {relaisAn, relaisAus};
enum {warten, on, rechts, haltrechts, links, haltlinks, off};
byte schritt = warten;
byte zyklus = 20; //cycles
const byte maxzyklus = 20; //max cycles

void setup() {
  Serial.begin(115200);
  Serial.println(F("Start...."));
  pinMode(sensorLinksEnd, INPUT);
  pinMode(sensorRechtsEnd, INPUT);
  pinMode(startPin, INPUT);
  pinMode(stopPin,  INPUT);
  pinMode(relaisLinks, OUTPUT);
  digitalWrite(relaisLinks, relaisAus);
  pinMode(relaisRechts, OUTPUT);
  digitalWrite(relaisRechts, relaisAus);
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, LOW);
}

void loop() {
  schrittkette();
}

void schrittkette()
{
  static unsigned long lastmillis;
  const unsigned long pauseZeit = 5000; // in ms
  if (digitalRead(stopPin))
  {
    schritt = off;
  }
  switch (schritt)
  {
    case warten:
      if (digitalRead(startPin))
      {
        zyklus = 0;
        schritt = on;
      }
      digitalWrite(relaisRechts, relaisAus);
      digitalWrite(relaisLinks, relaisAus);
      break;
    case on:
      digitalWrite(LED_BUILTIN, HIGH);
      schritt = rechts;
      break;
    case rechts:
      digitalWrite(relaisRechts, relaisAn);
      if (digitalRead(sensorRechtsEnd))
      {
        digitalWrite(relaisRechts, relaisAus);
        schritt = haltrechts;
        lastmillis = millis();
      }
      break;
    case haltrechts:
      digitalWrite(relaisRechts, relaisAus);
      digitalWrite(relaisLinks, relaisAus);
      if (millis() - lastmillis > pauseZeit)
      {
        schritt = links;
      }
      break;
    case links:
      digitalWrite(relaisRechts, relaisAus);
      digitalWrite(relaisLinks, relaisAn);
      if (digitalRead(sensorLinksEnd))
      {
        digitalWrite(relaisLinks, relaisAus);
        schritt = haltlinks;
        lastmillis = millis();
      }
      break;
    case haltlinks:
      digitalWrite(relaisRechts, relaisAus);
      digitalWrite(relaisLinks, relaisAus);
      if (millis() - lastmillis > pauseZeit)
      {
        if (zyklus == maxzyklus)
        {
          schritt = off;
        }
        else
        {
          zyklus++;
          schritt = rechts;
        }
      }
      break;
    case off:
      digitalWrite(LED_BUILTIN, LOW);
      schritt = warten;
      break;
  }
}

What have you tried so far? With what exactly do you have problems? And please include your code in your question (not in the comments please)

The wording in your question's subject makes me wonder if you've read what const does.

@timemage thanks for the reply. Ok the const is only read-only. What woul be a alternative for that? How i can post here my complete Code? Sorry it´s the first time here

I put the complete Code in the first question

The alternative would be to not use the const keyword there. If it shouldn't be constant, then don't use the const keyword. For your whole question: You could divide that up into reading buttons and into changing variables. With which do you have problems exactly and what have you tried so far? Have you googled for tutorials on how to read buttons?

@chrisl  I know now that I can't use const. I would need I think a unsigned int or better a unsigned long. I want to be able to change a big number. Something around 60000 cycles.  It was over the tutorials that I was able to make my start and stop buttons. But unfortunately to change a variable like I want I didn't found until now nothing that I could understand. I'm a complete beginner in c++ coding. What I have until now is taking out from examples or asking for some tips. If you know a tutorial who would help for this particular situation, I would appreciate your help

@CarlosCosta is it maxzyklus that you wish to use as your cycle counter variable?

Thanks for the help everybody. I found a solution.

How I can put on a easy way here my Code to show?

@CarlosCosta If you have found a solution to your problem, you can write an own answer to your question and accept that as correct. Glad you found a solution and are willing to share it. +1

The const keyword tells the C/C++ compiler that the variable is a constant and cannot be changed in your code anymore.
Simply remove const and you can modify maxzyklus by using 2 digital inputs.
byte maxzyklus = 20; //max cycles


text:
Passing a method pointer
I created a small library, which takes a callback function:
MyClass::add_callback(bool (*callback_function)(), byte behaviour) {
  // ...
  bool result = callback_function();
  // ...
}

So far, I'm using it for periodic polling (for which I don't want to use ISR interrupts). However, I like to use it for other periodic calls that require a state. A simple example is a blinking light, which has an on-off state, as well as knowledge when the next state change needs to occur.
I like to change this method or add another method that takes a method, instead of a function. How should I do this? I'm struggling with the C basics, but answers on StackOverflow seem foccused to more modern C variants. For example, this great answer on Stackoverflow recommends to use boost::bind, but I rather not include such a large dependency.
What I'm looking for is something akin to:
MyClass::add_callback(void *obj, bool (*callback_method)(), byte behaviour) {
  // ...
  bool result = Object::callback_method(&obj);
  // ...
}

where Object::callback_method(&obj); should be equivalent to Object obj; bool result = obj.callback_method();.
For bonus points, is it possible to make this independent on the Object class?
I'm happy for pointers to other sites (like StackOverflow), provided it is applicable to a bare Arduino program.

In case you wonder why I'm not using ISR, I'm a bit of a novice with the Arduino and C. My hardware is a ftDuino, and the Ftduino library uses timers and interrupts on the ATmega32u4, and I want to avoid conflicts for now.

The easiest method I know to do this would be to use a "C"-style wrapper for the member function call. This is in fact done to interface C callbacks with C++ objects.
You could do it like this:
struct Blinky {
  //state etc.
  bool isOn() { return /* something useful */ true; }
};

// The "C" wrapper for the callback
bool Blinky_callback(void *vblinky)
{
  return static_cast<Blinky*>(vblinky)->isOn();
}

struct MyClass {
  void add_callback(void *obj, bool (*callback_method)(void *), byte behaviour) {
    // ...
    bool result = callback_method(obj);
    // ...
  }
};

// Globals
MyClass c;
Blinky b;

void setup() {
  c.add_callback(&b, Blinky_callback, 0);
}

A slightly tidier way with a static member (functionally identical):
struct Blinky {
  //state etc.
  bool isOn() { return /* something useful */ true; }

  static bool callback(void *vblinky) {
    return static_cast<Blinky*>(vblinky)->isOn();
  }
};

// ...
c.add_callback(&b, Blinky::callback, 0);

Other variants would be using inheritance and virtual functions.
// Abstract base class
struct Sensor {
  virtual bool do_check() = 0;
};

struct Blinky : public Sensor {
  bool do_check() override { return true; }
}

Then you can have your add_callback look like:
void MyClass::add_sensor(Sensor *sensor) {
  // ...
  bool result = sensor->do_check();
  // ...
}

This is relatively nice to code with, and the compiler has a fighting chance at keeping your code typesafe, if all the "things" you want to control can conform to the same interface. The virtual dispatch won't cost much more (if anything) than the static wrapper in the previous example. You "pay" a few bytes per class and one pointer per instance for the virtual table though.
More modern techniques would involve templates and/or lambdas, or perhaps std::function, but all that seems overkill if your need is as described (and might generate a lot more code than you're expecting, or do dynamic allocations for std::function which is best avoided in context).

Remark: if you want to do it with (non-static) member function pointers, it is possible but the syntax is hairy:
void add_callback(Blinky *obj, bool (Blinky::*callback_method)(), byte behaviour) {
  // ...
  bool result = (obj->*callback_method)();
  // ...
}

And you're tied to that class. Unless you make add_callback a template, but beware extra codegen.

Thanks for such an extensive answer so quickly. I'll have a look and mark as read once I fully grasp it. At least it give me some good pointers. I seem to be struggling a bit which level of abstraction to use for microcontrollers. Turning back to C after a rather long time of Python and friends, it's interesting to see how poor C's memory management is, and how poor Python's instance protection are. Your answer helps me understand what sort of introspection I can expect from C, especially on an Arduino platform with few high-level libraries.

@MacFreek: none of the code I posted (or that you posted) is C. It is all C++. (And C++ is not modern C, they are two different languages). Look up "RAII" for how you should deal with memory management/object lifetime management. A lot of what you'll find won't be a great fit for small embedded projects, but the core idea is important. (The acronym sucks though.)

You are right. I used "C" because my Arduino code mostly uses plain functions and globals, rather than classes (which is fine for this purpose).

I'm not sure if this is a C vs. C++ syntax, or historic/modern constructs, but I noted that the Arduino IDE allows archaic constructs. For example, you can leave out the this-> in methods, or leave out the std:: prefix for type definitions. I found the hard way when delay() in my method did not call the Arduino function, but this->delay(). Would there be a way to make the IDE more strict, and only allow recommended constructs, so I only learn things the right way?

Thanks for your code examples. I now understand that I need a wrapper function, preferably in the stateful class with the called method. I was trying to solve it in the calling instance, without wrapper.

I don't know if you can change the compiler options used by the IDE (uses -std=gnu++11 -fpermissive which is not super strict), there might be questions on this site about this already. Leaving out this whenever you can is standard practice, you rarely need it. A missing std:: prefix should be a compile error, but there are several ways for a name to be brought into scope.

Your answer uses structs instead of classes. Is that recommended, or personal preference?

The only difference between the two is that struct give public access by default whereas class gives private. So struct is simpler for simple examples. The rest is a matter of style/preference.


text:
How to convert kitchen timer code into a countdown
I found this code for a kitchen timer, it was the closest thing to a countdown. The code is here:

#include <LiquidCrystal.h>

const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

signed short minutes, secondes;
char timeline[16];

void setup() {

  lcd.begin(16, 2);
  lcd.print("Chronometre :");

}

void loop() {

  lcd.setCursor(0, 1);
  sprintf(timeline,"%0.2d mins %0.2d secs", minutes, secondes);
  lcd.print(timeline);

  delay(1000);
  secondes++;

  if (secondes == 60)
  {
    secondes = 0;
    minutes ++;
  }

}

How do I convert it properly for it to countdown from 1 minute and 30 seconds?

How about initializing the time variables secondes and minutes with the values for 1:30 and then instead of incrementing them decrementing? And of course checking for seconds to be below zero for decrementing the minutes. Have you tried that?

I didnt know how to initailize that. Could you offer some code?

You should really do some basic C/C++ and Arduino tutorials, when you want to do Arduino. Otherwise you will not have much fun. Also we are not a free coding service. Look at the code where the mentioned variables are defined. Give each a fitting value by writing an = after the name and then the value. In the loop() you replace the ++ after the variable names with -- to decrement them. Then in the if condition secondes < 0) and inside the if statement secondes = 59. Thats as far as I will go here. With some tutorials and experimenting you will be able to understand that code.

I didnt know how to initailize that.  ... what do you think that line such as secondes = 0; does?

"customize this code i found" is not why we're here. I mean, this is really trivial. Break the problem up into smaller steps and ask for help when you get stuck. Use Serial.println() a lot when you start coding. a lot.

@chrisl  I know this isn't a free coding service. It was a simple question. Is there anything wrong with that?

@JamesChristaldi No, absolutely nothing wrong with asking question. This wasn't to scold you. I just think, that your question leaves basically two ways of answering here: Writing the code for you or giving you a basic C/C++ course. The first one is frowned upon here for some good reasons. The second one is done way better by the many basic C/C++ tutorials/courses on the web. Thus I gave a comment about the needed steps and left it to you to learn the corresponding C/C++ syntax in one of the tutorials/courses.

But this is Arduino not C/C++

Right? Am I wrong on that?

Arduino code is basically C/C++ including Arduino.h, which defines the Arduino-related functions like digitalRead() and much more. If you're able to program C/C++ programming Arduino will be a lot easier because you understand how to initalize variables, use loops, etc.

As a start, you need to initalise the secondes and minutes variables to 30 and 1 respectively.
replace signed short minutes, secondes; with:
signed short minutes = 1;
signed short secondes = 30;

Next thing I notice is that the code you have provided counts up and you have requested that it count down.
Change secondes++; and minutes++; with:
secondes--;
minutes--;

Lastly you need to change the logic for when the secondes and minutes variables reach zero.
If the secondes variable reaches zero but the minutes variable is greater than zero, then you decrement the minutes (using the line of code provided above) and top-up the secondes with 59.
secondes = 59;

You will need to check the value of the secondes and minutes variables using a couple of if...else statements.
if (secondes == 0 && minutes == 0) {
    // insert your timer finished code here
}
else if ( secondes == 0 && minutes > 0) {
    minutes--;
    secondes = 59;
}
else {
    // Error - your code should not reach here.
    // Display an error message on the LCD
}

This if..else statement will need to go at the top of your loop instead of the end.

Thank you so much!!

The first thing I recommend is that you don't use sprintf(). Your sketch "program storage space" drops from 3502 bytes down to 1928 bytes by NOT using that function call, and dynamic memory used drops from 101 to 79 bytes.
I would recommend an OOP design that would make it easy to add functionality, like the ability to start, stop and reset the timer.
// Arduino Uno, IDE version 1.8.9
// 2330 bytes (7%) of program storage space.
// Global variables use 201 bytes (9%) of dynamic memory.
class CountdownTimer{

  private:

    byte m_hour;
    byte m_minute;
    byte m_second;
    byte m_timerActive;
    byte m_timerComplete;
    unsigned long m_previousMillis;

  public:

    CountdownTimer():
      m_hour(0),
      m_minute(0),
      m_second(0),
      m_timerActive(0),
      m_timerComplete(0),
      m_previousMillis(0){}

    bool Update(){

      if(m_hour == 0 && m_minute == 0 && m_second == 0){
        m_timerComplete = 1;
        return 0;
      }

      if(m_timerActive && (millis() - m_previousMillis >= 1000)){
        m_previousMillis += 1000;
        m_second--;
        if(m_second == 255){
          m_second = 59;
          m_minute--;
          if(m_minute == 255){
            m_minute = 59;
            m_hour--;
            if(m_hour == 255){
              m_hour = 0;
            }
          }
        }
        return 1;
      }
      else{
        return 0;
      }
    }

    byte GetIsTimerComplete(){
      return m_timerComplete;
    }

    void SetHour(byte hour){
      m_hour = constrain(hour, 0, 23);
    }

    void SetMinute(byte minute){
      m_minute = constrain(minute, 0, 59);
    }

    void SetSecond(byte second){
      m_second = constrain(second, 0, 59);
    }

    void Start(){
      m_timerActive = 1;
    }

    void Stop(){
      m_timerActive = 0;
    }

    void ReStart(){
      m_timerActive = 1;
      m_timerComplete = 0;
      m_previousMillis = millis();
    }

    void PrintTimeRemaining(){
      if(m_hour < 10){Serial.print("0");}
      Serial.print(m_hour);
      Serial.print(":");
      if(m_minute < 10){Serial.print("0");}
      Serial.print(m_minute);
      Serial.print(":");
      if(m_second < 10){Serial.print("0");}
      Serial.println(m_second);
    }

};

// Make a copy of the object to work with.
CountdownTimer myCountdownTimer;

void setup(){

  // Built in pin 13 LED timer completed indicator.
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, LOW);

  // Test output to the serial monitor.
  Serial.begin(9600);

  // Set the countdown timer values,
  // start the countdown timer and
  // print the initial timer setting.
  myCountdownTimer.SetHour(0);
  myCountdownTimer.SetMinute(1);
  myCountdownTimer.SetSecond(30);
  myCountdownTimer.Start();
  myCountdownTimer.PrintTimeRemaining();
}

void loop(){

  // Call the Update function as fast as possible.
  if(myCountdownTimer.Update()){
    myCountdownTimer.PrintTimeRemaining();
  }

  // Turn on the Uno's Pin 13 LED once timer is complete.
  if(myCountdownTimer.GetIsTimerComplete()){
    digitalWrite(LED_BUILTIN, HIGH);
  }

}


text:
Current difference between pinMode(pin, INPUT_PULLUP) and digitalWrite(pin, HIGH)?
Does pin 5 or pin 6 use more power if they're just being used as a signal to an external device?
pinMode(5, INPUT_PULLUP);

pinMode(6, OUTPUT);
digitalWrite(6, HIGH);

.
EDIT:  Thanks to some links below, I hopped thru a series of threads until I found the website www.gammon.com.au/power which did tests with a 328 and found the following results with the pins disconnected (which is different than my question but seems relevant nonetheless):
In SLEEP_MODE_PWR_DOWN:

All pins as outputs, and LOW: 0.35 µA.
All pins as outputs, and HIGH: 1.86 µA.
All pins as inputs, and LOW (in other words, internal pull-ups disabled): 0.35 µA (same as before).
All pins as inputs, and HIGH (in other words, internal pull-ups enabled): 1.25 µA.

See also resistor - does INPUT_PULLUP use power?.

It all depends on the external device. If it has high-impedance inputs,
then it makes no difference. The Arduino itself has high-impedance on
its pins configured as INPUT. If the device draws current from this
signal, then chances are it will draw more current from an OUTOUT
HIGH than from an INPUT_PULLUP. How much more? We cannot say without
knowing the specifics of that device.
If you model the device as a simple resistor to ground (which is almost
certainly overly naive), then the current draw is
I = VCC / (R + Ro)
where R is the value of the resistor and Ro the output
resistance of the Arduino: about 25 Ω for an OUTPUT and
32 kΩ for an INPUT_PULLUP.

Thanks, for us noobs is the signal wire to most transistors/MOSFETs considered high-impedance?

@rfii: The input of a MOSFET (the gate) is high impedance (it's actually capacitive, thus high impedance for DC). The input of a BJT (the base) is low impedance, and it needs a current-limiting resistor.


text:
What is happening when digitalWrite(pinname, LOW) is invoked after pinMode(pinname, INPUT_PULLUP)?
I read the Arduino official docs on digitalWrite and am confused about what is happening from an electrical perspective when digitalWrite is invoked on INPUT_PULLUP pins.
Say my code says this:
pinMode(4, INPUT_PULLUP);
digitalWrite(4, LOW);

The docs say:

If the pin is configured as an INPUT, digitalWrite() will enable
(HIGH) or disable (LOW) the internal pullup on the input pin. It is
recommended to set the pinMode() to INPUT_PULLUP to enable the
internal pull-up resistor. See the Digital Pins tutorial for more
information.

Does this mean pin 4 is floating or is it at ground?  Are those two lines of code equivalent to pinMode(4, OUTPUT); digitalWrite(LOW);  ?

look at section 14.2 of https://ww1.microchip.com/downloads/en/DeviceDoc/ATmega48A-PA-88A-PA-168A-PA-328-P-DS-DS40002061B.pdf

Thanks, I a noob in EE and arduino so I think I need some help understanding what this doc means.  I'm trying to get at what kind of behavior to expect.  Are you also saying this is chip dependent?

definitely chip dependent, but probably very much the similar

It's pretty explicitly stated there in your quote: if you write a LOW when in INPUT mode it disables the pullup resistor. That's all it does.
pinMode(4, INPUT);
digitalWrite(4, HIGH);

is exactly the same as:
pinMode(4, INPUT_PULLUP);

And
pinMode(4, INPUT_PULLUP);
digitalWrite(4, LOW);

is exactly the same as
pinMode(4, INPUT);

Of course this exploits a peculiarity of the AVR's IO block, but any decent core will emulate that functionality for compatibility with older code.

Thanks, can you address the part of the question about if pinMode(4, INPUT); leaves the pin floating or if it is at GND?

A pin set to INPUT with no pullup and not connected to anything is always floating. It can never output anything or be set to any level unless it is explicitly set to OUTPUT.


text:
Set interrupts that are not GPIO or Timer in ESP32
I am making a project on ESP32. It reads certain sensor values, stores them in RTC memory and sends them by MQTT after a certain time. I wish that it transmits data immediately if there is a difference of, say 10 units, via an interrupt. I suppose this is not possible by GPIO interrupts and obviously not by a timer as I wish it to happen only if a condition is true and not periodically.
I searched on the internet but couldn't find anything except GPIO and Timer interrupts.
I am working on Arduino IDE.
Is what I want possible and if yes, how. Please also give a certain example that is in Arduino language for me to study. Also, if it is possible using GPIO interrupts, please tell me how.
Thank you in advance

send it in loop()

There is no such thing as an "interrupt on a value changing" since that is something that only exists in software, and interrupts are things triggered by hardware.
All you can do is check the value in loop() and send the data if the value is above your threshold. If you want to wake from sleep then you will have to do that periodically through other means.

could one use the 32's low power co-cpu and an assembly routine to avoid the wakeup just to compute the difference?