text:
ATmega328P - Problem using timer 2 for tone generation
I'm simply trying to use timer 2 for tone generation and what I get is a very faint and strange tone (almost like its modulated somehow as there is a "pulsing" to it). Here's my simple code:
#include <Arduino.h>

#define SPEAKER_PORT PORTC
#define SPEAKER_BIT 2

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

  TCCR2A = _BV(WGM21);  // CTC mode
  TCCR2B = _BV(CS20);   // clk/1

  OCR2A = 200;  // 8-bit timer, so keep less than 256
  bitSet(TIMSK2, OCIE2A);  // enable OCR2A interrupt
}

void loop()
{
  // NOP
}

ISR(TIMER2_COMPA_vect)
{
  SPEAKER_PORT ^= _BV(SPEAKER_BIT);
}

Any obvious mistakes? Thanks for your help!

I tried the code on an Uno and as you say, it does sound odd.
By my calculations, the frequency is 40kHz (16MHz/(200 x 2)), which is above the threshold of hearing. The sound we are actually hearing is probably the 3rd or 5th harmonic, at a reduced intensity and perhaps subject to jitter.
I tried changing
TCCR2B = _BV(CS20);   // clk/1
to
TCCR2B = _BV(CS21);   // clk/8
which should mean that the frequency is now 5kHz (16MHz/8/(200 x 2)).
It sounds cleaner.

Just posted an answer with a similar conclusion, as I had cross-posted to AVRFreaks.net and got similar advice. Thanks for the help! Glad to validate that this was reproducible for you. I'll mark yours as the solution.

Looks like my tone frequency was possibly just too high for the buzzer I was using, causing strange output.
Adjusting the clock divider fixed the issue. That is, I changed the following:
TCCR2B = _BV(CS20);   // clk/1

to
TCCR2B = _BV(CS22) | _BV(CS20);  // clk/128

and now I get reasonable-sounding tones.
Note that the clock divider you choose is ultimately driven by what frequency range you want to support, and the bit width of the timer. The formula is something like:
freq = 16000000 / d / n / 2

where d is the clock divider value (like 128), and n is the counter value at which to interrupt (what goes in OCR2A for instance). n must fit into the bit width of the specific timer (on ATmega328P timer 1 is 16-bits wide, and timer 2 is 8-bits wide).
Hope this is helpful for anyone else running into these issues. Thanks so much to Kartman over at AVRFreaks.net for pointing me in the right direction.

If you drive the speaker pin from an interrupt, you will inevitably have
some jitter, as the interrupt request will sometimes fire while the CPU
is processing another ISR. This can lead to one of the levels being held
for longer than expected, which in turn leads to spurious frequencies in
the output. Note that these are not really harmonics (harmonics always
have frequencies higher than the fundamental), but rather beating
between different interrupt sources. That's why you are able to hear
something even though the fundamental is well above the hearing range.
If you want to have a clean PWM signal, you should instead generate it
in hardware. Timer 2 for example can drive pins 11 (OC2A) and 3 (OC2B).
See the bits COM2{A1,A0,B1,B0} in TCCR2A.


text:
Converting each digit in an integer to its respective ASCII characters
For example what would be the process of converting the integer 1023 into ascii characters of
0x31 (1)
0x30 (0)
0x32 (2)
0x33 (3)
Not looking for any library functions (I know of Serial.print() and what not). I am trying to serially communicate an integer to the serial monitor, and I'd like to know what the process would be for an algorithm to take an integer and make each digit its corresponding ascii character

Is this what you are trying to do? http://www.cplusplus.com/reference/cstdlib/itoa/

If you search "c++ implementation itoa" you can find examples for this

how about float value? can float value convert using itoa()?

To convert a whole number to a char array in one go use the itoa function. That sounds like what you actually need.
To convert one digit from decimal to ascii just add '0', the ascii value for a 0. If you just want to try to understand what's going on, it's something like this.
char result[4] = {0};
int num = 345;

int digit = num % 10;  // get the 5 off the end
result[2] = digit + '0';  // convert to ascii and store
num /= 10;   // get rid of the 5
digit = num % 10;   // get the 4 off the end
result[1] = digit + '0';  // convert to ascii and store
num /= 10;   // get rid of the 4
digit = num % 10;   // get the 3 off the end
result[0] = digit + '0';  // convert to ascii and store

Serial.print(result);  // prints "345"

source: Stack Exchange

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

sort: votes


text:
vk2828u7g5lf GPS module over SoftwareSerial
So my goal was simple. Trying to get a GPS speed, and show it on a display (later use it to control a stepper motor). I am using the vk2828u7g5lf GPS module from Banggood, which after days of tinkering and trying several tutorials, I managed to make it work with ONLY the following code:
    boolean gpsStatus[] = {false, false, false, false, false, false, false};
unsigned long start;

#include <SoftwareSerial.h>
SoftwareSerial gpsSerial(3,2); // RX, TX

void setup()
{
  gpsSerial.begin(9600);
  // START OUR SERIAL DEBUG PORT
  Serial.begin(19200);
  //
  //Settings Array contains the following settings: [0]NavMode, [1]DataRate1, [2]DataRate2, [3]PortRateByte1, [4]PortRateByte2, [5]PortRateByte3,
  //[6]NMEA GLL Sentence, [7]NMEA GSA Sentence, [8]NMEA GSV Sentence, [9]NMEA RMC Sentence, [10]NMEA VTG Sentence
  //NavMode:
  //Pedestrian Mode    = 0x03
  //Automotive Mode    = 0x04
  //Sea Mode           = 0x05
  //Airborne < 1G Mode = 0x06
  //
  //DataRate:
  //1Hz     = 0xE8 0x03
  //2Hz     = 0xF4 0x01
  //3.33Hz  = 0x2C 0x01
  //4Hz     = 0xFA 0x00
  //
  //PortRate:
  //4800   = C0 12 00
  //9600   = 80 25 00
  //19200  = 00 4B 00  **SOFTWARESERIAL LIMIT FOR ARDUINO UNO R3!**
  //38400  = 00 96 00  **SOFTWARESERIAL LIMIT FOR ARDUINO MEGA 2560!**
  //57600  = 00 E1 00
  //115200 = 00 C2 01
  //230400 = 00 84 03
  //
  //NMEA Messages:
  //OFF = 0x00
  //ON  = 0x01
  //
  byte settingsArray[] = {0x03, 0xFA, 0x00, 0x00, 0xE1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; //
  configureUblox(settingsArray);
}

void loop()
{
  while(1) {
    if(gpsSerial.available())
    {
    // THIS IS THE MAIN LOOP JUST READS IN FROM THE GPS SERIAL AND ECHOS OUT TO THE ARDUINO SERIAL.
    Serial.write(gpsSerial.read());
    }
  }
}

void configureUblox(byte *settingsArrayPointer) {
  byte gpsSetSuccess = 0;
  Serial.println("Configuring u-Blox GPS initial state...");

  //Generate the configuration string for Navigation Mode
  byte setNav[] = {0xB5, 0x62, 0x06, 0x24, 0x24, 0x00, 0xFF, 0xFF, *settingsArrayPointer, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10, 0x27, 0x00, 0x00, 0x05, 0x00, 0xFA, 0x00, 0xFA, 0x00, 0x64, 0x00, 0x2C, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
  calcChecksum(&setNav[2], sizeof(setNav) - 4);

  //Generate the configuration string for Data Rate
  byte setDataRate[] = {0xB5, 0x62, 0x06, 0x08, 0x06, 0x00, settingsArrayPointer[1], settingsArrayPointer[2], 0x01, 0x00, 0x01, 0x00, 0x00, 0x00};
  calcChecksum(&setDataRate[2], sizeof(setDataRate) - 4);

  //Generate the configuration string for Baud Rate
  byte setPortRate[] = {0xB5, 0x62, 0x06, 0x00, 0x14, 0x00, 0x01, 0x00, 0x00, 0x00, 0xD0, 0x08, 0x00, 0x00, settingsArrayPointer[3], settingsArrayPointer[4], settingsArrayPointer[5], 0x00, 0x07, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
  calcChecksum(&setPortRate[2], sizeof(setPortRate) - 4);

  byte setGLL[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x2B};
  byte setGSA[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x32};
  byte setGSV[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x39};
  byte setRMC[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04, 0x40};
  byte setVTG[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x46};

  delay(2500);

  while(gpsSetSuccess < 3)
  {
    Serial.print("Setting Navigation Mode... ");
    sendUBX(&setNav[0], sizeof(setNav));  //Send UBX Packet
    gpsSetSuccess += getUBX_ACK(&setNav[2]); //Passes Class ID and Message ID to the ACK Receive function
    if (gpsSetSuccess == 5) {
      gpsSetSuccess -= 4;
      setBaud(settingsArrayPointer[4]);
      delay(1500);
      byte lowerPortRate[] = {0xB5, 0x62, 0x06, 0x00, 0x14, 0x00, 0x01, 0x00, 0x00, 0x00, 0xD0, 0x08, 0x00, 0x00, 0x80, 0x25, 0x00, 0x00, 0x07, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA2, 0xB5};
      sendUBX(lowerPortRate, sizeof(lowerPortRate));
      gpsSerial.begin(9600);
      delay(2000);
    }
    if(gpsSetSuccess == 6) gpsSetSuccess -= 4;
    if (gpsSetSuccess == 10) gpsStatus[0] = true;
  }
  if (gpsSetSuccess == 3) Serial.println("Navigation mode configuration failed.");
  gpsSetSuccess = 0;
  while(gpsSetSuccess < 3) {
    Serial.print("Setting Data Update Rate... ");
    sendUBX(&setDataRate[0], sizeof(setDataRate));  //Send UBX Packet
    gpsSetSuccess += getUBX_ACK(&setDataRate[2]); //Passes Class ID and Message ID to the ACK Receive function
    if (gpsSetSuccess == 10) gpsStatus[1] = true;
    if (gpsSetSuccess == 5 | gpsSetSuccess == 6) gpsSetSuccess -= 4;
  }
  if (gpsSetSuccess == 3) Serial.println("Data update mode configuration failed.");
  gpsSetSuccess = 0;

  while(gpsSetSuccess < 3 && settingsArrayPointer[6] == 0x00) {
    Serial.print("Deactivating NMEA GLL Messages ");
    sendUBX(setGLL, sizeof(setGLL));
    gpsSetSuccess += getUBX_ACK(&setGLL[2]);
    if (gpsSetSuccess == 10) gpsStatus[2] = true;
    if (gpsSetSuccess == 5 | gpsSetSuccess == 6) gpsSetSuccess -= 4;
  }
  if (gpsSetSuccess == 3) Serial.println("NMEA GLL Message Deactivation Failed!");
  gpsSetSuccess = 0;

  while(gpsSetSuccess < 3 && settingsArrayPointer[7] == 0x00) {
    Serial.print("Deactivating NMEA GSA Messages ");
    sendUBX(setGSA, sizeof(setGSA));
    gpsSetSuccess += getUBX_ACK(&setGSA[2]);
    if (gpsSetSuccess == 10) gpsStatus[3] = true;
    if (gpsSetSuccess == 5 | gpsSetSuccess == 6) gpsSetSuccess -= 4;
  }
  if (gpsSetSuccess == 3) Serial.println("NMEA GSA Message Deactivation Failed!");
  gpsSetSuccess = 0;

  while(gpsSetSuccess < 3 && settingsArrayPointer[8] == 0x00) {
    Serial.print("Deactivating NMEA GSV Messages ");
    sendUBX(setGSV, sizeof(setGSV));
    gpsSetSuccess += getUBX_ACK(&setGSV[2]);
    if (gpsSetSuccess == 10) gpsStatus[4] = true;
    if (gpsSetSuccess == 5 | gpsSetSuccess == 6) gpsSetSuccess -= 4;
  }
  if (gpsSetSuccess == 3) Serial.println("NMEA GSV Message Deactivation Failed!");
  gpsSetSuccess = 0;

  while(gpsSetSuccess < 3 && settingsArrayPointer[9] == 0x00) {
    Serial.print("Deactivating NMEA RMC Messages ");
    sendUBX(setRMC, sizeof(setRMC));
    gpsSetSuccess += getUBX_ACK(&setRMC[2]);
    if (gpsSetSuccess == 10) gpsStatus[5] = true;
    if (gpsSetSuccess == 5 | gpsSetSuccess == 6) gpsSetSuccess -= 4;
  }
  if (gpsSetSuccess == 3) Serial.println("NMEA RMC Message Deactivation Failed!");
  gpsSetSuccess = 0;

  while(gpsSetSuccess < 3 && settingsArrayPointer[10] == 0x00) {
    Serial.print("Deactivating NMEA VTG Messages ");
    sendUBX(setVTG, sizeof(setVTG));
    gpsSetSuccess += getUBX_ACK(&setVTG[2]);
    if (gpsSetSuccess == 10) gpsStatus[6] = true;
    if (gpsSetSuccess == 5 | gpsSetSuccess == 6) gpsSetSuccess -= 4;
  }
  if (gpsSetSuccess == 3) Serial.println("NMEA VTG Message Deactivation Failed!");

  gpsSetSuccess = 0;
  if (settingsArrayPointer[4] != 0x25) {
    Serial.print("Setting Port Baud Rate... ");
    sendUBX(&setPortRate[0], sizeof(setPortRate));
    setBaud(settingsArrayPointer[4]);
    Serial.println("Success!");
    delay(500);
  }
}

void calcChecksum(byte *checksumPayload, byte payloadSize) {
  byte CK_A = 0, CK_B = 0;
  for (int i = 0; i < payloadSize ;i++) {
    CK_A = CK_A + *checksumPayload;
    CK_B = CK_B + CK_A;
    checksumPayload++;
  }
  *checksumPayload = CK_A;
  checksumPayload++;
  *checksumPayload = CK_B;
}

void sendUBX(byte *UBXmsg, byte msgLength) {
  for(int i = 0; i < msgLength; i++) {
    gpsSerial.write(UBXmsg[i]);
    gpsSerial.flush();
  }
  gpsSerial.println();
  gpsSerial.flush();
}

byte getUBX_ACK(byte *msgID) {
  byte CK_A = 0, CK_B = 0;
  byte incoming_char;
  boolean headerReceived = false;
  unsigned long ackWait = millis();
  byte ackPacket[10] = {0xB5, 0x62, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
  int i = 0;
  while (1) {
    if (gpsSerial.available()) {
      incoming_char = gpsSerial.read();
      if (incoming_char == ackPacket[i]) {
        i++;
      }
      else if (i > 2) {
        ackPacket[i] = incoming_char;
        i++;
      }
    }
    if (i > 9) break;
    if ((millis() - ackWait) > 1500) {
      Serial.println("ACK Timeout");
      return 5;
    }
    if (i == 4 && ackPacket[3] == 0x00) {
      Serial.println("NAK Received");
      return 1;
    }
  }

  for (i = 2; i < 8 ;i++) {
  CK_A = CK_A + ackPacket[i];
  CK_B = CK_B + CK_A;
  }
  if (msgID[0] == ackPacket[6] && msgID[1] == ackPacket[7] && CK_A == ackPacket[8] && CK_B == ackPacket[9]) {
    Serial.println("Success!");
    Serial.print("ACK Received! ");
    printHex(ackPacket, sizeof(ackPacket));
    return 10;
        }
  else {
    Serial.print("ACK Checksum Failure: ");
    printHex(ackPacket, sizeof(ackPacket));
    delay(1000);
    return 1;
  }
}

void printHex(uint8_t *data, uint8_t length) // prints 8-bit data in hex
{
  char tmp[length*2+1];
  byte first ;
  int j=0;
  for (byte i = 0; i < length; i++)
  {
    first = (data[i] >> 4) | 48;
    if (first > 57) tmp[j] = first + (byte)7;
    else tmp[j] = first ;
    j++;

    first = (data[i] & 0x0F) | 48;
    if (first > 57) tmp[j] = first + (byte)7;
    else tmp[j] = first;
    j++;
  }
  tmp[length*2] = 0;
  for (byte i = 0, j = 0; i < sizeof(tmp); i++) {
    Serial.print(tmp[i]);
    if (j == 1) {
      Serial.print(" ");
      j = 0;
    }
    else j++;
  }
  Serial.println();
}

void setBaud(byte baudSetting) {
  if (baudSetting == 0x12) gpsSerial.begin(4800);
  if (baudSetting == 0x4B) gpsSerial.begin(19200);
  if (baudSetting == 0x96) gpsSerial.begin(38400);
  if (baudSetting == 0xE1) gpsSerial.begin(57600);
  if (baudSetting == 0xC2) gpsSerial.begin(115200);
  if (baudSetting == 0x84) gpsSerial.begin(230400);
}

However, this one doesn't have a simple getSpeed() function, so I've tried to move to a library like TinyGPS that does have said function. Everything compiles fine, but it seems I am not getting a GPS signal with this script, while I have an accurate reading with about 7 satellites of the first script. I've triple checked the baud rates, and they all match, so I am stuck here.
    #include <SoftwareSerial.h>

#include <TinyGPS.h>

/* This sample code demonstrates the normal use of a TinyGPS object.
   It requires the use of SoftwareSerial, and assumes that you have a
   4800-baud serial GPS device hooked up on pins 4(rx) and 3(tx).
*/

TinyGPS gps;
SoftwareSerial ss(3,2);

static void smartdelay(unsigned long ms);
static void print_float(float val, float invalid, int len, int prec);
static void print_int(unsigned long val, unsigned long invalid, int len);
static void print_date(TinyGPS &gps);
static void print_str(const char *str, int len);

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

  Serial.print("Testing TinyGPS library v. "); Serial.println(TinyGPS::library_version());
  Serial.println("by Mikal Hart");
  Serial.println();
  Serial.println("Sats HDOP Latitude  Longitude  Fix  Date       Time     Date Alt    Course Speed Card  Distance Course Card  Chars Sentences Checksum");
  Serial.println("          (deg)     (deg)      Age                      Age  (m)    --- from GPS ----  ---- to London  ----  RX    RX        Fail");
  Serial.println("-------------------------------------------------------------------------------------------------------------------------------------");

  ss.begin(9600);
}

void loop()
{
  float flat, flon;
  unsigned long age, date, time, chars = 0;
  unsigned short sentences = 0, failed = 0;
  static const double LONDON_LAT = 51.508131, LONDON_LON = -0.128002;

  print_int(gps.satellites(), TinyGPS::GPS_INVALID_SATELLITES, 5);
  print_int(gps.hdop(), TinyGPS::GPS_INVALID_HDOP, 5);
  gps.f_get_position(&flat, &flon, &age);
  print_float(flat, TinyGPS::GPS_INVALID_F_ANGLE, 10, 6);
  print_float(flon, TinyGPS::GPS_INVALID_F_ANGLE, 11, 6);
  print_int(age, TinyGPS::GPS_INVALID_AGE, 5);
  print_date(gps);
  print_float(gps.f_altitude(), TinyGPS::GPS_INVALID_F_ALTITUDE, 7, 2);
  print_float(gps.f_course(), TinyGPS::GPS_INVALID_F_ANGLE, 7, 2);
  print_float(gps.f_speed_kmph(), TinyGPS::GPS_INVALID_F_SPEED, 6, 2);
  print_str(gps.f_course() == TinyGPS::GPS_INVALID_F_ANGLE ? "*** " : TinyGPS::cardinal(gps.f_course()), 6);
  print_int(flat == TinyGPS::GPS_INVALID_F_ANGLE ? 0xFFFFFFFF : (unsigned long)TinyGPS::distance_between(flat, flon, LONDON_LAT, LONDON_LON) / 1000, 0xFFFFFFFF, 9);
  print_float(flat == TinyGPS::GPS_INVALID_F_ANGLE ? TinyGPS::GPS_INVALID_F_ANGLE : TinyGPS::course_to(flat, flon, LONDON_LAT, LONDON_LON), TinyGPS::GPS_INVALID_F_ANGLE, 7, 2);
  print_str(flat == TinyGPS::GPS_INVALID_F_ANGLE ? "*** " : TinyGPS::cardinal(TinyGPS::course_to(flat, flon, LONDON_LAT, LONDON_LON)), 6);

  gps.stats(&chars, &sentences, &failed);
  print_int(chars, 0xFFFFFFFF, 6);
  print_int(sentences, 0xFFFFFFFF, 10);
  print_int(failed, 0xFFFFFFFF, 9);
  Serial.println();

  smartdelay(1000);
}

static void smartdelay(unsigned long ms)
{
  unsigned long start = millis();
  do
  {
    while (ss.available())
      gps.encode(ss.read());
  } while (millis() - start < ms);
}

static void print_float(float val, float invalid, int len, int prec)
{
  if (val == invalid)
  {
    while (len-- > 1)
      Serial.print('*');
    Serial.print(' ');
  }
  else
  {
    Serial.print(val, prec);
    int vi = abs((int)val);
    int flen = prec + (val < 0.0 ? 2 : 1); // . and -
    flen += vi >= 1000 ? 4 : vi >= 100 ? 3 : vi >= 10 ? 2 : 1;
    for (int i=flen; i<len; ++i)
      Serial.print(' ');
  }
  smartdelay(0);
}

static void print_int(unsigned long val, unsigned long invalid, int len)
{
  char sz[32];
  if (val == invalid)
    strcpy(sz, "*******");
  else
    sprintf(sz, "%ld", val);
  sz[len] = 0;
  for (int i=strlen(sz); i<len; ++i)
    sz[i] = ' ';
  if (len > 0)
    sz[len-1] = ' ';
  Serial.print(sz);
  smartdelay(0);
}

static void print_date(TinyGPS &gps)
{
  int year;
  byte month, day, hour, minute, second, hundredths;
  unsigned long age;
  gps.crack_datetime(&year, &month, &day, &hour, &minute, &second, &hundredths, &age);
  if (age == TinyGPS::GPS_INVALID_AGE)
    Serial.print("********** ******** ");
  else
  {
    char sz[32];
    sprintf(sz, "%02d/%02d/%02d %02d:%02d:%02d ",
        month, day, year, hour, minute, second);
    Serial.print(sz);
  }
  print_int(age, TinyGPS::GPS_INVALID_AGE, 5);
  smartdelay(0);
}

static void print_str(const char *str, int len)
{
  int slen = strlen(str);
  for (int i=0; i<len; ++i)
    Serial.print(i<slen ? str[i] : ' ');
  smartdelay(0);
}

The result of the last script looks like this:
Testing TinyGPS library v. 13
by Mikal Hart

Sats HDOP Latitude  Longitude  Fix  Date       Time     Date Alt    Course Speed Card  Distance Course Card  Chars Sentences Checksum
          (deg)     (deg)      Age                      Age  (m)    --- from GPS ----  ---- to London  ----  RX    RX        Fail
-------------------------------------------------------------------------------------------------------------------------------------
**** **** ********* ********** **** ********** ******** **** ****** ****** ***** ***   *******  ****** ***   0     0         0
**** **** ********* ********** **** ********** ******** **** ****** ****** ***** ***   *******  ****** ***   52    0         0
**** **** ********* ********** **** ********** ******** **** ****** ****** ***** ***   *******  ****** ***   104   0         0
**** **** ********* ********** **** ********** ******** **** ****** ****** ***** ***   *******  ****** ***   169   0         0
**** **** ********* ********** **** ********** ******** **** ****** ****** ***** ***   *******  ****** ***   221   0         0

A list of libraries I've tried:
 - NeoGPS
 - NeoGPS (customized version of a forum)
 - TineGPS
 - AdafruitGPS
And some more random (video) tutorials online. If anyone could help me out on this one, I would be highly grateful! (and perhaps keep some hair on my head)

So it turned out it was a loose connection facepalm. Anyway, it still is far from usable. Now the data starts with a blank line, followed by actual gps data. Problem is that even without moving my module, the lat/long/and height (?) Is still moving around allot?

The clue lies in this part of your first sketch:
//NMEA Messages:
//OFF = 0x00
//ON  = 0x01
//
byte settingsArray[] = {0x03, 0xFA, 0x00, 0x00, 0xE1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; //
configureUblox(settingsArray);

The final entry in your configuration is 0x00 which is "turn off NEMA messages".
There's two things to note here:

You are not configuring the GPS receiver in your second code, and
All other GPS libraries of note parse NEMA messages, which your first code turns off.

You will need to replicate the configuration code from your first sketch in your second sketch, but turning ON NEMA messages.

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


text:
Using a 48 characters char[] for PROGMEM
I am trying to create a charliplexed display of 6x8 LEDS using a Arduino Nano with the ATMega328p chip. Because of the limited storage I am trying to use PROGMEM. I did my research and found some usefull examples, but when I try to create a char[] of 48 charaters (0 = LED off, 1 = LED on), the monitor only shows a line filled with squares. Im not sure what this indicates, but when I limit the amount of characters to lets say 10, it works as expected. I made sure the buffer size matches the amount of max characters. What am I missing here?
I know it would be easier to use a multiplexer, but I prefer to find a working solution using progmem since this is a assignment where I would like to have my students find a solution to store the "LED data" for the whole alphabet without using external memory or a multiplexer chip. If this simply is not possible, I will look into using other hardware.
TIA!
This is the code I am using:
#include <avr/pgmspace.h>
const char string_0[] PROGMEM = "000000000000000000000000000000000000000000000000"; // "String 0" etc are strings to store - change to suit.
const char string_1[] PROGMEM = "String 1";
const char string_2[] PROGMEM = "String 2";
const char string_3[] PROGMEM = "String 3";
const char string_4[] PROGMEM = "String 4";
const char string_5[] PROGMEM = "String 5";

// Then set up a table to refer to your strings.

const char *const string_table[] PROGMEM = {string_0, string_1, string_2, string_3, string_4, string_5};

char buffer[48];  // make sure this is large enough for the largest string it must hold

void setup() {
  Serial.begin(9600);
  while (!Serial);  // wait for serial port to connect. Needed for native USB
  Serial.println("OK");
}

void loop() {
  /* Using the string table in program memory requires the use of special functions to retrieve the data.
     The strcpy_P function copies a string from program space to a string in RAM ("buffer").
     Make sure your receiving string in RAM  is large enough to hold whatever
     you are retrieving from program space. */

  for (int i = 0; i < 6; i++) {
    strcpy_P(buffer, (char *)pgm_read_word(&(string_table[i])));  // Necessary casts and dereferencing, just copy.
    Serial.println(buffer);
    delay(500);

do you have place for terminating zero in buffer?

Obviously not. char buffer[49]; will fix that issue. Also I wouldn't bother to place string_table in PROGMEM if you are not desperate to save 12 bytes of RAM.

Yep, that was the issue... Since I never worded with progmem before, I didnt know I needed to use an extra index for it. Thanks!
Eventually I will be adding every letter of the alphabet, including capitals and non capitals. And maybe if there is some more space, some symbols haha.

You could try strlcpy_P(buffer, ...pgm..., sizeof(buffer)). That is a extra 'l' as in Lima.


text:
Arduino Nano 33 BLE work with its Bluetooth and GPS synchronously?
I am using Arduino nano 33 Sense BLE in which I want GPS to run and display its location . The GPS module which I am using is Adafruit GPS. I want both Bluetooth and GPS to run synchronously. But only one of them shows output. I have tried Adafruit-GPS library with the Hardware Serial but it shows the GPS location not the Bluetooth working.
I also checked the code individually both are working well.I have used the example of Adafruit-GPS library->GPS_HardwareSerial_Parsing and ArduinoBLE library->LED , these codes both work individually well but when I have combined them and tried to make it run only the GPS shows its location the bluetooth seems to be not working.Below is the combined code:
#include <Adafruit_GPS.h>
#include <ArduinoBLE.h>

// what's the name of the hardware serial port?
#define GPSSerial Serial1
// Connect to the GPS on the hardware port
Adafruit_GPS GPS(&GPSSerial);
// Set GPSECHO to 'false' to turn off echoing the GPS data to the Serial console
// Set to 'true' if you want to debug and listen to the raw GPS sentences
#define GPSECHO false
uint32_t timer = millis();

BLEService ledService("19B10000-E8F2-537E-4F6C-D104768A1214"); // BLE LED Service
// BLE LED Switch Characteristic - custom 128-bit UUID, read and writable by central
BLEByteCharacteristic switchCharacteristic("19B10001-E8F2-537E-4F6C-D104768A1214", BLERead | BLEWrite);
const int ledPin = LED_BUILTIN; // pin to use for the LED

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

 // 9600 NMEA is the default baud rate for Adafruit MTK GPS's- some use 4800
  GPS.begin(9600);
  GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCGGA);
  GPS.sendCommand(PMTK_SET_NMEA_UPDATE_1HZ); // 1 Hz update rate

  pinMode(ledPin, OUTPUT);
  BLE.setLocalName("LED");
  BLE.setAdvertisedService(ledService);
  // add the characteristic to the service
  ledService.addCharacteristic(switchCharacteristic);
  // add service
  BLE.addService(ledService);
  // set the initial value for the characeristic:
  switchCharacteristic.writeValue(0);
  // start advertising
  BLE.advertise();

  delay(1000);
}

void loop()
{
  char c = GPS.read();

  BLEDevice central = BLE.central();

  if (GPS.newNMEAreceived()) {
   // Serial.println(GPS.lastNMEA()); // this also sets the newNMEAreceived() flag to false
    if (!GPS.parse(GPS.lastNMEA())) // this also sets the newNMEAreceived() flag to false
      return; // we can fail to parse a sentence in which case we should just wait for another
  }

 if (timer > millis()) timer = millis();

//BLE code to connect to bluetooth

  // if a central is connected to peripheral:
  if (central) {
    Serial.print("Connected to central: ");
    // print the central's MAC address:
    Serial.println(central.address());
    // while the central is still connected to peripheral:
    while (central.connected()) {
      // if the remote device wrote to the characteristic,
      // use the value to control the LED:
      if (switchCharacteristic.written()) {
        if (switchCharacteristic.value()) {   // any value other than 0
          Serial.println("LED on");
          digitalWrite(ledPin, HIGH);         // will turn the LED on
        } else {                              // a 0 value
          Serial.println(F("LED off"));
          digitalWrite(ledPin, LOW);          // will turn the LED off
        }
      }
    }
    // when the central disconnects, print it out:
    Serial.print(F("Disconnected from central: "));
    Serial.println(central.address());
  }

//GPS to print latitude and longitude
  // approximately every 5 seconds or so, print out the current stats
  if (millis() - timer > 5000) {
    timer = millis(); // reset the timer
    Serial.print("Fix: "); Serial.print((int)GPS.fix);
    Serial.print(" quality: "); Serial.println((int)GPS.fixquality);
    if (GPS.fix) {
      Serial.print("Location: ");
      Serial.print(GPS.latitude, 4); Serial.print(GPS.lat);
      Serial.print(", ");
      Serial.print(GPS.longitude, 4); Serial.println(GPS.lon);
    }
  }

}

return; // we can fail to parse skips the rest of the loop()


text:
How to change the update rate in TinyGPS++?
I am working with TinyGPS++ library and Arduino-nano and I want to change the update rate.
I worked before with Adafruit GPS and uses the below code for updating it.
// Set the update rate
 GPS.sendCommand(PMTK_SET_NMEA_UPDATE_1HZ);   // 1 Hz update rate

I have also worked with NMEAGPS.h to update every 30sec.
gps.send_P( &gpsPort, F("PMTK220,30000") );        //update 1time in 30s

So how to change the upsate rate for TinyGPS++ library? as I want to update 1 time in 30seconds.

I looked at the source code and it appears that the library checks for a new complete sentance as fast as you call the method encode.  From your question, it is not clear if this library is working too slow or too fast for your application.  But it does appear your application is in charge of any desired delay.

@st2000 I just want an update after every 30second.

If your code does not need to do anything else, I'm thinking you can simply call delay milliseconds with 30000 each time in between calling encode().  If you would like to do other things during that time, then you need to implement a state machine.

can you explain with an example?

This example TinyGPS code appears to attempt to grab new GPS data once a second.  Guessing, if you increase the loop counter on line 30 from 1000 to 30000, the delay will increase from once a second to once every 30 seconds.

@st2000 I am using TinyGPS++ library and the above code is of TinyGPS which is correct answer to my question but there is a function isUpdated in TinyGPS++ , so that function and the code you suggested are equivalent?

Is this the code for TinyGPS you are talking about? I don't see "isUpdated" anywhere in the code.

Oh, bet you are talking about his other GPS project.  But I still don't see "isUpdated" in his source code.  Ah, that's because the code is so short he just puts the code in the header file.  All that's going on is that he returns (exposes) the true / false bool value of a private variable named updated.  The method does not accept a formal parameter.  And all it can return is True or False. Doesn't look like it has anything to do w/time.  It just gets set true or false depending on the last method you happen to call.

@st2000 So should i use the code you suggested or else use isUpdated ? this code uses isUpdated

This is the example code. Not the library code. But you know that, right? It looks like "isUpdated" is used so as to only allow printing the values after the GPS module has updated the values. But that's likely way faster than what you want.  You wanted to print out data once every 30 seconds. So you have to add your own code to add a delay. A GPS module is a complex radio receiver with its own processor of which you do not have full control. On a good day it might see a dozen US (GPS), Russian (GLONASS) and other satellites. With that many satellites there will be a lot of data to print out.


text:
millis() function works with inline code and gives output but when creating own library it doesn't works
I am creating library for GPS to use in my project. I am using Adafruit GPS and its library to create my own library in which I am using millis() function to display the GPS Location after 1 minute (60s). So when I created my inline code the function works very well and also displays location after 60s. But I created header and cpp file for my own library, in which it doesn't gives any error but the results(location) is not displayed. Doesn't shows any output. So I printed the time which is 0 (attached the output screenshot)
My code updates the GPS every 30s and prints the location every 1 minute.It also checks the if old location is equal to new location in every 1minute.
I think there is problem with my libaray or with the millis() function. I am new to Arduino programming , please help me with this.
My inline code is:
#include <Adafruit_GPS.h>
#include <SoftwareSerial.h>

SoftwareSerial mySerial(11, 10);
Adafruit_GPS GPS(&mySerial);

#define GPSECHO  true
uint32_t timer = millis();
float old_lat,old_lon,new_lat,new_lon;

void setup()
{

  Serial.begin(9600);
  delay(1000);
  Serial.println("Adafruit GPS library basic test!");
  GPS.begin(9600);
  GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCGGA);
  GPS.sendCommand("$PMTK220,30000*1F");
  mySerial.println(PMTK_Q_RELEASE);
}

void loop()                     // run over and over again
{
  char c = GPS.read();
  if (GPS.newNMEAreceived()) {
    //Serial.println(GPS.lastNMEA());   // this also sets the newNMEAreceived() flag to false
    if (!GPS.parse(GPS.lastNMEA()))   // this also sets the newNMEAreceived() flag to false
      return;  // we can fail to parse a sentence in which case we should just wait for another
  }

if (GPS.fix) {

      old_lat = GPS.latitudeDegrees;
      old_lon = GPS.longitudeDegrees;
      if (timer > millis())  timer = millis();
      if (millis() - timer > 60000) {
        timer = millis();
          Serial.println("Location 1 minute:");
          displaytime();
          new_lat = GPS.latitudeDegrees;
          new_lon = GPS.longitudeDegrees;

          if (new_lat == old_lat){
            new_lat = old_lat;
          }
          else{
            new_lat = GPS.latitudeDegrees;
          }
          Serial.print("Final Latitude: ");
          Serial.println(new_lat,6);

          if (new_lon == old_lon){
            new_lon = old_lon;
          }
          else{
            new_lon = GPS.longitudeDegrees;
          }
          Serial.print("Final Longitude: ");
          Serial.println(new_lon,6);

}
}
}

void displaytime(){
    Serial.print("\nTime: ");
    if (GPS.hour < 10) { Serial.print('0'); }
    Serial.print(GPS.hour, DEC); Serial.print(':');
    if (GPS.minute < 10) { Serial.print('0'); }
    Serial.print(GPS.minute, DEC); Serial.print(':');
    if (GPS.seconds < 10) { Serial.print('0'); }
    Serial.print(GPS.seconds, DEC); Serial.print('.');
    if (GPS.milliseconds < 10) {
      Serial.print("00");
    } else if (GPS.milliseconds > 9 && GPS.milliseconds < 100) {
      Serial.print("0");
    }
    Serial.println(GPS.milliseconds);
}

My header file is :
/*
 * GPS.h - library used to show Latitude and Longitude
 */

 #ifndef GPS_Loc_h
 #define GPS_Loc_h

 #include "Arduino.h"

class SoftwareSerial;
class Adafruit_GPS;

 class GPS_Loc
 {
  public:
    GPS_Loc();
    void displaytime();
    void displayloc();
    uint32_t timer;
    float old_lat,old_lon,new_lat,new_lon;
 };

 #endif

My cpp file is:
/*
 * GPS_Loc.cpp - library used to show Latitude and Longitude
 */

 #include "Arduino.h"
 #include "GPS_Loc.h"

 #include "Adafruit_GPS.h"
 #include "SoftwareSerial.h"

 #define GPSECHO  true

SoftwareSerial mySerial(11,10);
Adafruit_GPS GPS(&mySerial);

GPS_Loc::GPS_Loc()
{
  timer = millis();
  old_lat = old_lat;
  old_lon = old_lon;
  new_lat = new_lat;
  new_lon = new_lon;
}

void GPS_Loc::displayloc(){
  //Serial.println("Adafruit GPS library basic test!");
  GPS.begin(9600);
  GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCGGA);
  GPS.sendCommand("$PMTK220,30000*1F");
  mySerial.println(PMTK_Q_RELEASE);
  char c = GPS.read();
  if (GPS.newNMEAreceived()) {
    //Serial.println(GPS.lastNMEA());   // this also sets the newNMEAreceived() flag to false
    if (!GPS.parse(GPS.lastNMEA()))   // this also sets the newNMEAreceived() flag to false
      return;  // we can fail to parse a sentence in which case we should just wait for another
    }

if (GPS.fix) {

      old_lat = GPS.latitudeDegrees;
      old_lon = GPS.longitudeDegrees;
      if (timer > millis())  timer = millis();
      if (millis() - timer > 60000) {
        timer = millis();
          Serial.println("Location 1 minute:");
          displaytime();
          new_lat = GPS.latitudeDegrees;
          new_lon = GPS.longitudeDegrees;

          if (new_lat == old_lat){
            new_lat = old_lat;
          }
          else{
            new_lat = GPS.latitudeDegrees;
          }
      Serial.print("Location lat: ");
          Serial.println(new_lat,6);

          if (new_lon == old_lon){
            new_lon = old_lon;
          }
          else{
            new_lon = GPS.longitudeDegrees;
          }

          Serial.print("Location long: ");
          Serial.println(new_lon,6);

}
}
}

void GPS_Loc::displaytime(){
    Serial.print("\nTime: ");
    if (GPS.hour < 10) { Serial.print('0'); }
    Serial.print(GPS.hour, DEC); Serial.print(':');
    if (GPS.minute < 10) { Serial.print('0'); }
    Serial.print(GPS.minute, DEC); Serial.print(':');
    if (GPS.seconds < 10) { Serial.print('0'); }
    Serial.print(GPS.seconds, DEC); Serial.print('.');
    if (GPS.milliseconds < 10) {
      Serial.print("00");
    } else if (GPS.milliseconds > 9 && GPS.milliseconds < 100) {
      Serial.print("0");
    }
    Serial.println(GPS.milliseconds);
}

My demo code using my own library is:
#include <GPS_Loc.h>

GPS_Loc bgps;

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

}

void loop() {
  // put your main code here, to run repeatedly:
  bgps.displaytime();
  bgps.displayloc();
}

Output of inline code

I think the problem might be with GPS.begin(9600);. You are initialize the serial connection every time you call displayLoc. But in the inline code, you only do this once. Try adding an init function to your class, that will setup the serial only once.

I think Gerben is on to something.  If you re-initialize the gps at every loop and then never give it time to acquire the gps signal then your if (GPS.fix) condition is never true and you never print out any other data.  All your timing code is inside the GPS.fix condition which doesn't happen until you have a fix.
Try putting the init code inside your contructor for your class. Somethink like :
GPS_Loc::GPS_Loc()
{
  timer = millis();
  old_lat = old_lat;
  old_lon = old_lon;
  new_lat = new_lat;
  new_lon = new_lon;

  //Serial.println("Adafruit GPS library basic test!");
  GPS.begin(9600);
  GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCGGA);
  GPS.sendCommand("$PMTK220,30000*1F");
  mySerial.println(PMTK_Q_RELEASE);
}

void GPS_Loc::displayloc(){
  delay(100); // short delay to stop a no-fix runaway
  char c = GPS.read();
  if (GPS.newNMEAreceived()) {
    //Serial.println(GPS.lastNMEA());   // this also sets the newNMEAreceived() flag to false
    if (!GPS.parse(GPS.lastNMEA()))   // this also sets the newNMEAreceived() flag to false
      return;  // we can fail to parse a sentence in which case we should just wait for another
    }

if (GPS.fix) {

It might also be useful to put a small delay somewhere in the code so that it won't loop like crazy before getting a fix.

Still I am not getting the output


text:
8 digit 7 segment display issues
I've been trying to follow a few tutorials on how to get the 7 segment to display simple output but none seem to work 100%.
It starts out fine. It increments the number across the screen and then writes 8s to all of them and then reverses. After a few loops however it starts to act weird. Here's a video link where it acts a bit weird (a few digits don't write correctly and fix themselves) and then at the end, it only displays half of the 8 digit display before it goes to 8s and crashes. https://youtu.be/LD_C7I_bGyc
Here's the code:
//We always have to include the library
#include "LedControl.h"

// pin 4 is connected to the DIN pin
// pin 2 is connected to the CLK pin
// pin 3 is connected to the CS pin
// 1 as we are only using 1 MAX7219
LedControl lc = LedControl(4, 2, 3, 1);

void setup(){
    // the zero refers to the MAX7219 number, it is zero for 1 chip
    lc.shutdown(0, false);// turn off power saving, enables display
    lc.setIntensity(0, 0);// sets brightness (0~15 possible values)
    lc.clearDisplay(0);// clear screen
}

void loop(){
    // numbers 7 to 0
    for (int a = 0; a < 8; a++){
        lc.setDigit(0, a, a, false);
        delay(100);
    }
    delay(1000);
    // display number 8 on all segments
    for (int a = 0; a < 8; a++){
        lc.setDigit(0, a, 8, false);
        delay(100);
    }
    delay(1000);

    for (int a = 8; a >= 0; a--){
        lc.setDigit(0, a, a, false);
        delay(100);
    }
}

Hardware:
   Arduino Uno: https://www.jaycar.com.au/duinotech-uno-r3-development-board/p/XC4410
   8 digit display: https://www.jaycar.com.au/8-digit-7-segment-display-module/p/XC3714
At this stage it's hard to tell if it's a hardware issue or if it's setup related. If someone could please give me some insight or maybe run it if they have the same hardware that would be fantastic.
Thanks!

You should switch your display on. Your setup() call to lc.setIntensity(0, 0) turns the display intensity to zero, try setting it to 15.

That's just the brightness. It was originally 15 during the day but at night I turned it down because it was too bright.

I wonder if you're timings are too fast. There's timing values in the datasheet at https://datasheets.maximintegrated.com/en/ds/MAX7219-MAX7221.pdf try slowing everything down a bit.

for (int a = 8; a >= 0; a--){ -- Why do you start with 8 and not with 7. The forward version go to 7 a < 8;. BTW: I enjoyed the question, because of the video. Cool Idea. ;-)

@Dougie you were pretty close. I posted an answer to the fix as it was actually the ground wire not being stable. I had previously changed all the wires that control the 8 digit however I never thought to change the power and ground wires to the board. Not having a stable ground wire would have messed up the communication and affect the timings a lot.

@PeterPaulKiefer the video was the only way I could think to show people to make them believe how weird it was acting :)

This was an unexpected result. @Dougie was pretty on to it. I didn't know how to adjust the timings as I was pretty sure the library took care of it, so the only thing I could think of was to redo all the wiring again. That's when I noticed that the ground wire pin into the board was half sticking out.
In the video you can see the ground pin at the top right. So it was making a connection (otherwise the whole thing wouldn't work), but after replacing the wire it runs fine. So that would have messed up the timings if the connection was unstable.

Well, it might have changed the values recognized by the chip. If you lose ground (no pun intended) the reference level is lost. A "low" (bit value 0) might be read as "high" (bit value 1) or vice versa. The timing will not change because of a missing ground connection.

I'm not an expert at this, but my guess was that the Arduino was sending the messages but since it wasn't grounding properly it was cutting out and therefore getting mixed messages during each timing round.

@the bussybee, I'll need to do some research as to how ground actually impacts it as I thought it just completed the circuit.

The last loop exceeds the limits of 8 Digits. You iterate 9 times (0-8).
   for (int a = 7; a >= 0; a--){
        lc.setDigit(0, a, a, false);
        delay(100);
    }

This is almost certainly the problem. (voted.) Array out-of-bounds problems cause lots of strange symptoms.

Annoyingly that didn't fix it. I'm guessing if it was then it would crash on the first main "loop" but it runs for a while before freaking out.


text:
ESP 01 calling Pushing Box API
I want to write my data on google sheets using ESP 01 and Arduino Nano.
So I copied code from some website I don't remember the website "how to send data on a local server" and modified it a bit.
But it is directly sending the data to the local server only.
Please help me to call Pushing box API and write on Google Sheets.
Here is my current code:

#include<SoftwareSerial.h>

SoftwareSerial comm(12,11); //setting Tx and Rx pins

String server=""; //variable for sending data to webpage
boolean No_IP=false; //variable to check for ip Address
String IP=""; //variable to store ip Address
char temp1='0';

int a=0;
int b=0;

void setup()
{
Serial.begin(9600);
comm.begin(9600);
wifi_init();
Serial.println("System Ready..");
}

void loop()
{
b=0;
Serial.println("Refresh Page");
while(b<1000)
{
b++;
while(comm.available())
{
if(comm.find("0,CONNECT"))
{
Serial.println("Starting");
sendToServer();
Serial.println("Finished");
delay(1000);
}
}
delay(1);
}
}

void findIp(int time1) //check for the availability of IP Address
{
int time2=millis();
while(time2+time1>millis())
{
while(comm.available()>0)
{
if(comm.find("IP has been read"))
{
No_IP=true;
}
}
}
}

void showIP()//Display the IP Address
{
IP="";
char ch=0;
while(1)
{
comm.println("AT+CIFSR");
while(comm.available()>0)
{
if(comm.find("STAIP,"))
{
delay(1000);
Serial.print("IP Address:");
while(comm.available()>0)
{
ch=comm.read();
if(ch=='+')
break;
IP+=ch;
}
}
if(ch=='+')
break;
}
if(ch=='+')
break;
delay(1000);
}
Serial.print(IP);
Serial.print("Port:");
Serial.println(80);
}

void establishConnection(String command, int timeOut) //Define the process for sending AT commands to module
{
int q=0;
while(1)
{
Serial.println(command);
comm.println(command);
while(comm.available())
{
if(comm.find("OK"))
q=8;
}
delay(timeOut);
if(q>5)
break;
q++;
}
if(q==8)
Serial.println("OK");
else
Serial.println("Error");
}

void wifi_init() //send AT commands to module
{
establishConnection("AT",100);
delay(1000);
establishConnection("AT+CWMODE=3",100);
delay(1000);
establishConnection("AT+CWQAP",100);
delay(1000);
establishConnection("AT+RST",5000);
delay(1000);

Serial.println("Connecting Wifi....");
establishConnection("AT+CWJAP=\"Leobotics\",\"leobotics123\"",7000); //provide your WiFi username and password here
delay(2000);
Serial.println("Wifi Connected");
showIP();
establishConnection("AT+CIPMUX=1",100);
establishConnection("AT+CIPSERVER=1,80",100);
}

void sendData(String server1)//send data to module
{
int p=0;
while(1)
{
unsigned int l=server1.length();
Serial.print("AT+CIPSEND=0,");
comm.print("AT+CIPSEND=0,");
Serial.println(l+2);
comm.println(l+2);
delay(100);
Serial.println(server1);
comm.println(server1);
}
}
void sendToServer()//send data to webpage
{
//String aquib = "http://busgetbeast.in";
sendData("http://api.pushingbox.com/pushingbox?devid=vBDFF4154ABE4F6F&humidityData=33&celData=44&fehrData=111&hicData=22&hifData=77");
      sendData(" HTTP/1.1");
      sendData("Host: ");
      sendData("api.pushingbox.com");
      sendData("User-Agent: ESP8266/1.0");
      sendData("Connection: close");
    // sendData();
delay(5000);
comm.println("AT+CIPCLOSE=0");
}

better use a library. it will get too complex for direct use of AT commands. WiFiEsp library or WiFiEspAT if you don't need SSL and you can flash AT 1.7 (SDK 3) to esp-01. or write a sketch for the esp for the networking part

I've used WiFiEsp Library, modifying the WebClient Example but still, its showing Data Packet Error (2)

where is CIPSTART in your sketch?

when i'm adding CIPSTART it showing me error on serial monitor


text:
Reading Data from Google Sheets using Nodemcu
I want to read and writ data on Google sheets using ESP8266 WIfi Nodemcu and I'm able to do it but the time interval between two writing row is 3 seconds which is too much. I can read data but I am able to read only the first row not any other rows i am not able to read even changing the URL parameters.
Here is My Code -

#include "ESP8266WiFi.h"
#include "HTTPSRedirect.h"
#include "DebugMacros.h"

// Fill ssid and password with your network credentials

const char* ssid = "Leobotics";

const char* password = "leobotics123";

int sheetHumid = 1;

int sheetTemp  = 2;

int sheetaqu   = 3;

String readaqu = "";

const char* host = "script.google.com";

// Replace with your own script id to make server side changes

const char *GScriptId = "AKfycbyu_JnX7F29Ea5cZUy7HdsFbv9W5UmedmNbhTwt5tznwRUiQhYS";

const int httpsPort = 443;

// echo | openssl s_client -connect script.google.com:443 |& openssl x509 -fingerprint -noout

const char* fingerprint = "ED:83:75:6B:83:FE:01:DE:BA:72:84:05:71:FA:CE:54:FB:6E:23:CA";

//const uint8_t fingerprint[20] = {};

// Write to Google Spreadsheet

String url = String("/macros/s/") + GScriptId + "/exec?value=Hello";

// Fetch Google Calendar events for 1 week ahead

String url2 = String("/macros/s/") + GScriptId + "/exec?cal";

// Read from Google Spreadsheet

String url3 = String("/macros/s/") + GScriptId + "/exec?read";

String payload_base =  "{\"command\": \"appendRow\", \
                    \"sheet_name\": \"Sheet1\", \
                    \"values\": ";
String payload = "";

HTTPSRedirect* client = nullptr;

// used to store the values of free stack and heap
// before the HTTPSRedirect object is instantiated
// so that they can be written to Google sheets
// upon instantiation

unsigned int free_heap_before = 10;

unsigned int free_stack_before = 20;

void setup() {

  Serial.begin(115200);

  Serial.print("Connecting to wifi: ");

  Serial.println(ssid);

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {

    delay(500);

    Serial.print(".");

  }

  Serial.println("");

  Serial.println("WiFi connected");

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

  // Use HTTPSRedirect class to create a new TLS connection

  client = new HTTPSRedirect(httpsPort);

  client->setInsecure();

  client->setPrintResponseBody(true);

  client->setContentTypeHeader("application/json");

  Serial.print("Connecting to ");

  Serial.println(host);

  // Try to connect for a maximum of 5 times
  bool flag = false;

  for (int i=0; iconnect(host, httpsPort);

    if (retval == 1) {

       flag = true;

       break;
    }

    else

      Serial.println("Connection failed. Retrying...");
  }

  if (!flag){

    Serial.print("Could not connect to server: ");

    Serial.println(host);

    Serial.println("Exiting...");

    return;
  }

}

void loop() {

  datasend();

  static int error_count = 0;

  static int connect_count = 0;

  const unsigned int MAX_CONNECT = 20;

  static bool flag = false;

  if (!flag){

    client = new HTTPSRedirect(httpsPort);

    client->setInsecure();

    flag = true;

    client->setPrintResponseBody(true);

    client->setContentTypeHeader("application/json");

  }

  if (client != nullptr){

    if (!client->connected()){

      client->connect(host, httpsPort);

      payload = payload_base + "\"" + sheetaqu + "," + sheetTemp + "," + sheetHumid + "\"}";

      client->POST(url2, host, payload, false);

    }
  }

  else{

    DPRINTLN("Error creating client object!");

    error_count = 5;

  }

  if (connect_count > MAX_CONNECT){

    connect_count = 0;

    flag = false;

    delete client;

    return;

  }

  Serial.println("GET Data from cell 'A1':");

  if (client->GET(url3, host)){

    ++connect_count;

    payload = payload_base + "\"" + readaqu + "," + sheetaqu + "," + sheetTemp + "," + sheetHumid + "\"}";

    Serial.println("RECIEVED DATA IS GIVEN BELOW   ");

    Serial.println("                              ");

    Serial.println("1");

    Serial.println(readaqu);

    Serial.println("2");

    Serial.println(sheetaqu);

    Serial.println("3");

    Serial.println(sheetTemp);

    Serial.println("4");

    Serial.println(sheetHumid);

    Serial.println("                              ");
    Serial.println("RECEIVE DATA PRINT IS OVER  ");

    sheetaqu ++;

    sheetTemp ++;

    sheetHumid ++;

  }
  else{

    ++error_count;

    DPRINT("Error-count while connecting: ");

    DPRINTLN(error_count);

  }

  Serial.println("POST append memory data to spreadsheet:");

  payload = payload_base + "\"" + sheetaqu + "," + sheetTemp + "," + sheetHumid + "\"}";

  if(client->POST(url2, host, payload)){

    ;
  }

  else{

    ++error_count;

    DPRINT("Error-count while connecting: ");

    DPRINTLN(error_count);

  }

  if (error_count > 3){

    Serial.println("Halting processor...");

    delete client;

    client = nullptr;

  }

  delay(4000);

}

void datasend()

{
   // Send memory data to Google Sheets

  payload = payload_base + "\"" + sheetaqu + "," + sheetTemp + "," + sheetHumid + "\"}";

  client->POST(url2, host, payload, false);

  payload = payload_base + "\"" + sheetaqu + "," + sheetTemp + "," + sheetHumid + "\"}";

  client->POST(url2, host, payload, false);

  // Note: setup() must finish within approx. 1s, or the the watchdog timer
  // will reset the chip. Hence don't put too many requests in setup()
  // ref: https://github.com/esp8266/Arduino/issues/34

  Serial.println("\nGET: Write into cell 'A1'");

  Serial.println("=========================");

  // fetch spreadsheet data

  client->GET(url, host);

  // Send memory data to Google Sheets

  payload = payload_base + "\"" + sheetaqu + "," + sheetTemp + "," + sheetHumid + "\"}";

  client->POST(url2, host, payload, false);

  Serial.println("\nGET: Fetch Google Calendar Data:");

  Serial.println("================================");

  // fetch spreadsheet data

  client->GET(url2, host);

  // Send memory data to Google Sheets

  payload = payload_base + "\"" + sheetaqu + "," + sheetTemp + "," + sheetHumid + "\"}";

  client->POST(url2, host, payload, false);

  Serial.println("\nSeries of GET and POST requests");

  Serial.println("===============================");

  // delete HTTPSRedirect object

  delete client;

  client = nullptr;
}

Why the 4s delay at the end of loop?

Actually that code is copied from a website, I don't know the specific function of that delay of 4 second

I think you'll need to modify your Google Script for that Sheet so that whatever function you are invoking to GET row data takes in an additional parameter for the row value.
Then just add the Javascript logic within that function for retrieving the data at that passed-in row index to be returned.
Does that make sense?


text:
Turn on/off low current device (LED) with Arduino
I am just starting with Arduino and my first project consists in switching a LED light with Arduino.
I know a relay must be use to control AC high voltage device (i.e. 240V), however, as my LED seems to be powered by DC 7V voltage (7V - 0.43A written on the power supply which is integrated within the outlet, so I can only access the low voltage wire), I am wondering how to control such a device.
Do I still need a relay or the Arduino can handle this on its own?

Do you have the LED datasheet?

It's the Jansjo lamp from Ikea. I copy below what's written on the outlet: MODEL: KMV-070-030-GS-3, PRI: 220-240V~50/60Hz 0.05A, SEC: 7V_-- 0.43A 3W    SELV

Look into MOSFET as a switch

You could probably run the Arduino from that same 7V supply. Negating the need for a separate adapter.

@chrisl: would you have a mosfet reference in mind which could do the job?

I have just found a relay (SRD-05VDC-SL-C) which can handle 10A/30V DC devices so I will start with this.

Use a power MOSFET transistor. This one from Sparkfun is an example: https://www.sparkfun.com/products/10213
If you use a relay you will probably need transistor and a separate power supply to drive the relay coils anyway, and will also need a flyback diode to protect the control circuit of the relay from the "back EMF" of the relay coils.
DO NOT try to drive relay coils directly from an Arduino digital pin. It will almost certainly fry the Arduino pin, and might destroy the entire Arduino.
A MOSFET transistor like the one I linked can be controlled directly from an Arduino GPIO line, and can switch DC loads of up to 60V and 30A.

Why would I need an extra power supply while the SRD-05VDC-SL-C relay can be driven with 5V, as output by the Arduino?

You can drive the control line of a relay like that with 5V, but it needs a 5V supply to drive the relay coils. It may be within the current limits of the Arudino's 5V line, but it might also cause the 5V line to bounce around as the relay energizes and de-energizes.

No You can easily achieve this by using a NPN Transistor....

simulate this circuit – Schematic created using CircuitLab
You can use BC548 NPN transistor for this is..
But make sure that ground of both emitter and arduino should be same....

This transistor is a poor recommendation because the Collector Current — Continuous for the BC548 is only 100mA, yet the LED load could be up to 430mA.


text:
What is the difference between a Hall effect sensor and an inductive one?
From what I have read, when placed within a magnetic field, a current will flow in both sensors.
My goal is to use this kind of sensors to guide a robot thanks to an existing automower loop wire, such as suggested in DIY Perimeter Wire Generator and Sensor.
I am thus wondering what is the difference between a Hall effect sensor and an inductive one such as the one described in the link above?

First they physically work differently. In the Hall effect sensor the electrons flowing through a plate will be deflected. Thus there will be a voltage perpendicular to the current, which can be measured. The voltage will be proportional to the magnetic field strengh. So you can sense a magnet, that is near the sensor, even if it doesn't move.
For the inductive sensor you have a guiding wire, that has an AC current flowing through it. This also means, that a magnetic field ist constantly building up and collapsing again around the wire. This change of magnetic field will induce an induction voltage in a nearby wire loop (the actual sensor). The frequency of that voltage is the same as of the guidance wire and the strength depends on the distance between the wires. So you are not measuring the magnetic field strength directly, but you measure how much it is changing (mathematically you differentiate).
Two different measurement methods which can be used to do the same thing. To guide a robot over a predefined course I would use the induction method (as long as the situation allows laying out wires), since it can be made less susceptible to noise. For that you can filter out all frequencies except of the used guiding frequency with a LC circuit. Or even better (though maybe not important) a lock-in amplifier. The hall sensor is an analog device, which can be very noisy.

Thus, regarding the robot guidance over a guiding wire, both sensors can do the job but measurements from the inductive one are less noisy?

Yes and no. I cannot say, which one is better as, as long as you are not using additional hardware. Both of them can be distorted by noise. But when you filter out all but the used induction frequency, the noise to signal ratio gets way better. For both methods you would have to test the needed current/guiding wire layout, since the magnetic field strength or it's change must be strong enough to measure it with the given sensor. I haven't build such thing myself, so I only can talk about the theory here


text:
How can I make my arduino start when a magnet is sensed, and stay running until the application determines it was to shut down
My thought was to use a magnetic reed switch to turn on the arduino.  But how do I keep it running if the magnet is moved?  The idea is that the application will determine when it is ok to shut off the power to the arduino.
I don't want any power usage when the system is dormant since it could be weeks between magnetic triggers.
Doug

You can connect a power MOSFET in parallel to the reed switch, that is controlled by the Arduino:

simulate this circuit – Schematic created using CircuitLab
The Arduino powers up, when the reed switch is activated. Then you can activate (drive HIGH) the pin connected to the MOSFET, so that the Arduino is still provided with the needed power through the MOSFET, if the reed switch turns off. If the correct time comes to turn the Arduino off, you can release the digital pin (drive LOW or high impedance/input), so that it get's pulled to low. That will deactivate the MOSFET, which cuts the power off the Arduino.

chrisl - I think this is exactly what I was looking for.  However, I have one question:  Since I am using 4 AA Batteries as a power source, should I connect the "Arduino 5V" connection in your diagram to the Vin pin instead?  Will there be any other issues since I am using a higher voltage? - Doug

No, the higher voltage should not be a problem (most MOSFETs have a rather high voltage limit). Only be sure, that the used MOSFET is rated for a current higher than what your total circuit needs. And it has to drive into saturation for 5V gate voltage

Put your Arduino into deep sleep and attach an interrupt to a pin that is monitoring your reed switch. Once triggered it can run your code before deep sleeping again

The LowPower library will help you to minimize the amount of power used by putting the Arduino to sleep. The Arduino will awaken once the magnetic reed switch triggers it, then you can execute some code before it goes back to sleep again.
There is an example sketch that may work for you:

// **** INCLUDES *****
#include "LowPower.h"

// Use pin 2 as wake up pin
const int wakeUpPin = 2;

void wakeUp()
{
    // Just a handler for the pin interrupt.
}

void setup()
{
    // Configure wake up pin as input.
    // This will consumes few uA of current.
    pinMode(wakeUpPin, INPUT);
}

void loop()
{
    // Allow wake up pin to trigger interrupt on low.
    attachInterrupt(0, wakeUp, LOW);

    // Enter power down state with ADC and BOD module disabled.
    // Wake up when wake up pin is low.
    LowPower.powerDown(SLEEP_FOREVER, ADC_OFF, BOD_OFF);

    // Disable external pin interrupt on wake up pin.
    detachInterrupt(0);

    // Do something here
    // Example: Read sensor, data logging, data transmission.
}

Thanks for this solution.  It's not exactly what I was looking for because of the power consumption (although it is very low!), but I plan on using this for other projects.


text:
Is there some better documentation somewhere for Arduino classes and API's?
For example, it looks like Serial extends HardwareSerial, which extends Stream, which extends Print. But I don't think you can figure this out by reading the reference documentation on https://www.arduino.cc/ and it doesn't appear that you can easily navigate the class hierarchy in the Arduino IDE. They seem to go out of their way to hide the class hierarchy?
I guess I'm spoiled by modern languages that have automatically generated documentation, but it seems like there should be a more complete reference somewhere?

I use Eclipse with Sloeber plugin. It gives me super powers in Arduino world

The point of Arduino is that it's targeted at people that don't need (or care) about such level of detail in the documentation.

There's an addon to MS VisualStudio (VisualMicro.com) to provide you with a real IDE allowing to drill down the provided core libraries.

What I did/do when loading a new core is generating a doxygen visualisation help class hierachy in HTML. Although most of the core libs have no detailed doxygen documenation the dot/graphviz solves the problem without installation of other IDEs (which also have their specific problems, or need a lot of learning). As an added bonus I can document my source code in a clean and transparent way available in most IDEs and OS.


text:
Using Arduino as contact to the world for linux box if app crashes
I am new to this micro controller thingie world so bare with me :)
Let me describe a scenario first.
Say I have a linux box for house automation embedded in a wall.
For security reasons is the only active access to the box the display mounted to the wall.
Another access would be via network and ssh but ssh is disabled.
Unfortunately does the web app sometimes crash and nothing goes. In the wake of that do I have to disassemble quite some stuff to get to the box and to revive it.
My Idea:
I can use a nfc or rfid sensor and hook it up to Arduino.
Would it be possible to make Arduino log on to the linux box and fire up and shutdown ssh?
I don't want to use Arduino Yun.
Is it achievable with an Arduino nano/Mega?
If not, which system would be your first choice to accomplish this task?
Thanks for your patience :)

What hardware is the Linux box? Something similar to a Raspberry Pi? Does it have a serial console? RS-232 or logic level? What logic voltage?

It has no rs232 but usb so attaching a rs232 to usb converter would be possible

Oh, a full scale micro PC in use.

Why should RFID be more secure, than SSH? If you use key-based authentication and only allow access from the local network or even only from specific devices, that should be plenty security. Or - if it is only the app, thats crashing - maybe you can write a small program, that checks if the app is still alive. I don't see the need for extra hardware, as long as not the whole linux crashes, in which case that might be the real security issue.

There's no reason why you couldn't start agetty on the /dev/ttyUSB0 or /dev/ttyACM0 of an Arduino board's USB interface - then get the Arduino to send the text required to log in and use sudo or su to run the commands to start or stop ssh. Seems very convoluted though. Simpler just to, as @chrisl says, to just run SSH but secure it to the local network.

I know that my approach is somewhat ..quirky.
But that is the way it has to go.
So Arduino can run linux commands? ...oh. let me guess. There is a library for this?

Yes, it's called HardwareSerial, you use it like this: Serial.println("sudo reboot").

Thanks for your help folks. :) You pushed me into the right direction.
It is now "just" a matter of reading documentation and make a decision in which direction to proceed.

If the web app crashes it should ideally restart. systemd has a mechanism for that. If the web app hangs, that's another thing. You could have a separate process monitor this. Then there is the case where the Pi crashes/hangs. The Pi actually has a hardware watchdog. This is a software problem, that can be solved in software. PS as a last resort you can power cycle the Pi to make it restart.

I will put our comments together in an answer.
You are overthinking the security issue. In my opinion, using RFID to reset the system is a bigger security thread, than using ssh the correct way. Normal RFID chips are susceptible to spoofing (copying an existing chip). Also the intruder could remove the RFID module to directly access the communication lines (depending on how much you will have accessible of the extra hardware). Also you can of course use the Serial interface of an Arduino to execute shell commands on your machine. You need a program on the machine to read the input and execute the commands (Majenko mentioned agetty for this). But is that really the best way? Using an Arduino here is a very hardware-ry way of solving a software issue. It is overly complex to do things this way and there are better options.
Instead you should really just use ssh with key-based authentication (disable password authentication). You can limit the ssh daemon to the local network (though, if you don't have configured corresponding port forwarding in your router, it isn't reachable from the internet either way), or - if you really want the additional security - to one specific device in your network. With a normal ssh key (I think 2048 bit is the standard), brute forcing is not a viable option for intruders. If you keep your private key save, there is very very little chance, that an intruder can get past that. You can also save the private key only on an USB stick, which you only use for resetting the machine. Also you can limit the commands, that the ssh user can execute, to only the resetting (like only allowing rebooting).
Depending on your actual security needs, you can choose, how far you want to go. I personally would just use key-based ssh limited to the local network. That should be plenty enough security and would also give you the possibility to access the machine, that is running in your home easier.

Or, if you really don't want to open ssh for the machine, you can write a simple watchdog program, that can run on the machine. Since the webapp is failing, you can write a simple python program (or any other language you like), which is regularly loading the webapp (how exactly depends largely on the webapp and the exact type of failure - may be a simple HTTP GET request) to check, if it is still alive. If the liveliness test fails for a defined number of times (let's say 3), it will reboot the machine.
This method does not require any access to the machine, but you will have to develop the liveliness test. Writing the program is then really simple.

All that said, it is not a good sign, that the app fails that often. You didn't write, what app that is, and what exactly fails. Maybe you are able to fix that issue directly. Or the developer of the app can, so maybe raise an issue on his platform (where the project is hosted).

You recap is nailing it pretty well.
I am aware of that this approach is not the best approach for a home network.
But it was just a scenario to help me to make  the point clear how and what to achieve.
I can tell you it is WAN based and the app is not failing that often.
It hangs max 1-2 times a year and the ssh approach with certificate works fine.
My scenario describes just the worst-case which until now not has happened.
This is just a pre-emptive action I am taking for convenience and saving time/money.


text:
Arduino detect order of objects
I'm trying to find a way to detect blocks being placed on grid on a table. The table will have fixed places where you can place the blocks, but the user is allowed to place the blocks in any free slot. I would like to have an Arduino poll the slots on the table and tell me which blocks are placed where.
I'm going to design the blocks with magnetic connections on the top and bottom to create a circuit as soon as they are placed.
What kind of chips can I use so that the arduino can give me the topology of the blocks when placed?

You need to constrain your problem further.  For example, if the Arduino is monitoring the placement of blocks the order of the stack can be inferred through inspection of the history of sensor activation.  However, if the Arduino needs to detect the order with out history - then the problem becomes difficult.

Interesting approach to use the timing / history.
However I'm not even sure how to detect the blocks at all at the moment. I don't know what chips to integrate into the table or the blocks to be able to detect them.

This is a situation where OneWire ROMs with unique serial numbers would be good.

"OneWire ROMs", I'll have to google that.  At the opposite end of the spectrum you can key the blocks (cut off a corner) to ensure their orientation with respect to the table and place magnets in unique places for each type.  Then use Hall Effect devices to sense them.

fixing the orientation is definitely a step in the right direction @st2000 !

I did look into a OneWire solution for arduino. It turns out that you can 'scan' for connected devices on OneWire, but it seems to be hard to use more than 1 arduino pin. I guess that would me I require 1 arduino per placement cell of the table @Majenko ?

It shouldn't be hard to have more than one pin - just have more than one OneWire object, each with a different pin. How many tile positions are you wanting to have?

@Majenko it's going to be like a chessboard, so a total of 64 positions. Stacks of objects could be up to 8 high.

That's quite a lot of pins to use for OneWire buses. I'd suggest maybe splitting the project down into sections. Maybe make a single strip of 8 controlled by a small Arduino (nano or micro or something) then put 8 of them together and have them communicate with a master one.

"64 positions. Stacks of objects could be up to 8 high" So... Wow, that's 512 objects.  I think you just left the Arduino realm and entered into Raspberry Pi using a camera and OpenCV.  You did say you would like a completely software defined solution. Well check out OpenCV.  You can look a projects like this and that for ideas.

You need to track unique objects in an 8x8 grid of slots? How many unique objects?
If the total number of objects is 112 or less, you could give each one a unique I2C address.
You'd add 4 circular electrical contacts in a "bulls-eye" configuration on the top and bottom of each object so that all the I2C pins would connect regardless of orientation. All objects in the same stack would be connected together on that stack's I2C bus.
You'd have an 8x8 multiplexer to connect to the I2C bus for each of your 64 grid positions in turn, and poll that bus for each of the possible I2C addresses. (Send a ping for each address and look for ACKs.)

Alternately, you could give every object a unique weight, varied by a power-of-two amount. (first object weighs 1000 grams. Second weighs 1001 grams (1000+2^0)) third object weighs 1002 grams (1000+2^1). Fourth object weighs 1004 grams (1000+2^2). Etc.)
Then you'd put a scale on each pad. Weigh the objects, modulo 1000 grams. That result, in binary, would give you flags for every object on that pad.

Or 2 circular electrical contacts on the top and bottom of each object, with resistors that have unique power-of-two resistance on each one, as Juraj suggests in their comment. Measure the resistance and you can figure out which set of objects is present.
The math would be simpler if you rigged the objects so that they made a series circuit through all objects present (put a normally closed switch on the top that shorts the top contacts of that object through its resistor if there's no object on top of it. If there is an object, the switch would open, and the objects on top would close the circuit.)

Or do you need to know where objects are located top-to-bottom in each stack?

Thanks @Duncan!
Luckily I don't need to know the order of the objects, as long as I have the count for each stack.
I'm going to try your I2C approach first, since I prefer a 'software' solution over a physical solution like weight and resistance.

How many unique objects do you need to deal with? Is it less than the 112 unique objects I2C supports?

@GuusBaggermans, I deleted my comment about the solution with resistors, because it would not detect individual objects, only the count on each stack. The I2C solution is not a software solution. You need to put a powered chip with I2C address in each block and you would still not detect the ordering. So the resistor is much simpler and requires only two interchangeable contacts on each side interchangeable side.


text:
MPU6050 Gyroscope does not give reliable readings
It gives reliable readings for a couple of seconds and then it becomes unreliable.
My arduino code is this:
#include<Wire.h>
const int MPU6050_addr=0x68;
int16_t AccX,AccY,AccZ,Temp,GyroX,GyroY,GyroZ;
void setup(){
  Wire.begin();
  Wire.beginTransmission(MPU6050_addr);
  Wire.write(0x6B);
  Wire.write(0);
  Wire.endTransmission(true);
  Serial.begin(9600);
}
void sendVector(float x, float y, float z) {
  Serial.print(x, 4);
  Serial.print("|");
  Serial.print(y, 4);
  Serial.print("|");
  Serial.println(z, 4);
}

void loop(){
  Wire.beginTransmission(MPU6050_addr);
  Wire.write(0x3B);
  Wire.endTransmission(false);
  Wire.requestFrom(MPU6050_addr,14,true);
  AccX=Wire.read()<<8|Wire.read();
  AccY=Wire.read()<<8|Wire.read();
  AccZ=Wire.read()<<8|Wire.read();
  Temp=Wire.read()<<8|Wire.read();
  GyroX=Wire.read()<<8|Wire.read();
  GyroY=Wire.read()<<8|Wire.read();
  GyroZ=Wire.read()<<8|Wire.read();
  //Serial.print(AccX);
  //Serial.print(AccY);
  //Serial.print(AccZ);
  //Serial.print(" || Temp = "); Serial.print(Temp/340.00+36.53);
  //Serial.print(" || GyroX = ");
  //Serial.println(GyroX);
  //Serial.print(" || GyroY = ");
  //Serial.println(GyroY);
  //Serial.print(" || GyroZ = ");
  //Serial.println(GyroZ);
  sendVector(GyroX, GyroY, GyroZ);
  delay(100);
}

The above sends data to unity which controls an object. The object works with the gyroscope and then due to the random readings it rotates quickly and randomly.

Have a look at an AHRS sensor fusion alogrithm which gives you quaternions/roll,pitch,yaw values and also makes values more stable.

I don't think you have given enough information to help you debug this, but i can try to give some advice:
First verify that the chip works correctly
Use the arduino plot monitor, and a sample program, to see the behavior of the chip and values over time; make sure its not a problem with the chip
Second verify that you are interpreting the values correctly
The MPU6050 outputs 16-bit data, but doesn't have 16-bit resolution, this means that the lower bits of the data are random, meaningless noise, and should be ignored/discarded.
If you are assuming that all 16 bits contain valid data, and your code is sensitive enough to be affected by those lower bits, then you will see unstable random data.
Third consider other (possible) obstacles
Try increasing the serial BAUD rate, you may be taking too much time and causing problems that way.
Maybe you are getting out of sync while reading from the chip, if there is additional data being sent, you could could build up a backlog in the buffer, and start interpreting messages incorrectly because you are reading part of one and part of another. Try using a library to talk to the chip, one that other people have used and is known to work; this could remove bugs you are blind to, or bugs that everyone will run into, but they have already been fixed in the library!


text:
How do I get my servo to turn using bluetooth, is this a glitch?
I'm very new to coding with arduino so please excuse my naivety, For an electronics assignment I am making a servo turn back and forth using a HM10 BLE however each time I press a button that sends '0' or '1' to the serial it also sends '200, '0' (being whatever i pressed), 250' all on different lines, so the servo tries turning to 200, 0, then 150 in a quick burst, making it spas out for a split second.
Is there any way i can get rid of the 200 and 250 in the serial or somehow make it only send the '0' or '1'
This is my code so far if needed:
  #include<SoftwareSerial.h>
#include<Servo.h>
Servo x;
int bttx=9;    //tx of bluetooth module is connected to pin 9 of arduino
int btrx=10;    //rx of bluetooth module is connected to pin 10 of arduino
SoftwareSerial bluetooth(bttx,btrx); //defines bluetooth as a dim and reads tx and rx from above

void setup()
{
  x.attach(11);        // servo is connected to pin 11 of arduino
  Serial.begin(9600);
  bluetooth.begin(9600);
}
void loop()
{
  if(bluetooth.available()>0)    //if bluetooth module is transmitting data
  {
    int pos=bluetooth.read(); // store the data in pos variable
    Serial.println(pos);
  }
}

Thankyou for the help and sorry again for the inconvenience, as I said I am only about a week into arduino :) anything helps

Sounds like the sending code on your smartphone isn't working correctly. You will have to fix that. As a workaround, if this sequence of bytes is always the same, you can read the whole sequence from the buffer, and only then set the servo to the desired position.

I agree with crisl, you should look at how your bluetooth signal is generated.
Another good practice is to filter your input signal, not send it straight through to an output. In your case that could be as simple as "if I get anything other than a 0 or a 1, discard and don't use it as a position".


text:
General confusion about how to start
I want to test around with my ESP32 and an E-Paper display - yet i am stuck at uploading sketches via Arduino IDE. I get those kind of errors:
avrdude: stk500_getsync() attempt 1 of 10: not in sync: resp=0x48

and looking into tools,i dont even see my board there - i bought it on amazon and the article just says "ILS - LOLIN32 Lite V1.0.0 Wifi and Bluetooth Board with ESP-32 Rev1 MicroPython 4MB FLASH".
What am i missing here? I am 99% sure i got the pins correct (finally), i got the USB-Serial driver, i got the right port - yet even a simple test sketch i found on the internet didnt work.

Uh.. have you installed ESP32 support in the Arduino IDE and have the correct board selected? Can you include a screenshot of your Arduino IDE when you try to upload the code?

what do you mean, "installed ESP32 support"? and i highly doubt i have the correct board selected i tried uploading multiple times on different board - but i dont know how to find out what board exactly i have in the IDE that. here is a screenshot: https://ibb.co/crQQLd

In the lower right corner you can see you have selected "Arduino Uno" board on COM3 as your target device. That's not what you want. You need to install the ESP32 Core for the Arduino IDE to be able to use the ESP32 boards and select it under Werkzeuge -> Board. Try to follow these instructions and check back if it worked: https://github.com/espressif/arduino-esp32/blob/master/docs/arduino-ide/windows.md or https://www.smart-prototyping.com/blog/How%20to%20Install-ESP32-Core-Arduino-IDE

aah, i never heard of such thing being required to install - i always thought that ESP32 is just a generic name for those dev boards and that arduino boards are ESP32 with different specs. thanks, i will try to get that working for now

Clarification: "Arduino" is a framework / core. It is a set of functions (like millis(), digitalWrite(), digitalRead(), so to say. There are very different Arduino-Compatible boards (most famous: Arduino Uno / Nano / Mega, ESP8266, ESP32, STM32..). But since these boards are all from entirely different architecture (AVR vs XTensa vs ARM ..), they all need a different implementation of the Arduino Core. Thus you need to extend your Arduino IDE with more Cores for different board types to use them with the Arduino Framework.

Now i understand - i guess its a little like a driver for Arduino running on my LOLIN32?

alright, everything set up, now it seems to be working (at least more than before) - but i get this error: (it appears twice, the first two words mean "invalid library"):
Ungültige Bibliothek C:\Program Files (x86)\Arduino\hardware\espressif\esp32\libraries\BLE in C:\Program Files (x86)\Arduino\hardware\espressif\esp32\libraries\BLE gefunden

You must execute a recursive git pull in Arduino/hardware/esp32: https://github.com/espressif/arduino-esp32/issues/766 . Did you install it by the downloaded ZIP file or via a git pull? Seems like you need the git pull, because the github ZIP doesn't contain sub-gits.

i downloaded the ZIP and i think i got all files i need via the python script that was included - i get a lot more feedback from the IDE now, it seems to be working, after pressing "upload" it ends with "leaving" and "hard resetting via RTS pin" - dont know if thats a good thing yet, i couldnt see any results on the board or on the display yet

I'd need a full log / screenshot for that. What exact sketch are you running? Can you try running the sketch https://github.com/espressif/arduino-esp32/blob/master/libraries/WiFi/examples/WiFiScan/WiFiScan.ino and look at the serial monitor at 115200 baud?

yes! i can see entries using the sketch you provided - i was using a LED  blinking sketch i found online and that did not blink the big blue LED on the board - the next step i want to take is using the example sketch for a 7.5" e-paper display that i got from the arduino folder, but uploading that never did anything even with (i suppose) correct pin mapping

You should be able to blink the LED if you remove LED_BUILTIN for 22 in the example blink sketch (see schematics here and here. However, connecting an E-Paper display should be posted as a different question with more information (code, wireup, ..).

i am confused - i used this sketch: http://www.arduino.cc/en/Tutorial/Blink
on my LOLIN32 but i only see a small, red LED blinking - i suppose that is not the right one, and it doesnt blink every 1 second aswell. what is that "LED_BUILTIN for 22" that you are talking about? excuse me if i am overlooking something obvious here

In the code, LED_BUILTIN appears 3 times. Replace every LED_BUILTIN by the number 22. The LED is on pin number 22 as I've shown you in the schematic diagram. Very likely LED_BUILTIN is just wrongly set by default. You're probably seeing that "CHARGE" LED flicker, not the one labeled "22"?

that might be true, now i understand - the sketch comments say that the LED_BUILTIN is set to the right pin by default - and yes, the 22 fixed it, thanks a lot - now i can finally move to the e-paper after fiddling around for more than a week!

The Arduino IDE does not have a core for the ESP32 installed by default.
The problem was solved by explicitly installing the ESP32-Arduino Core in the Arduino IDE according to their manuals

https://github.com/espressif/arduino-esp32/blob/master/docs/arduino-ide/windows.md
https://www.smart-prototyping.com/blog/How%20to%20Install-ESP32-Core-Arduino-IDE


text:
How to connect a 240x320 37-pin TFT to an Arduino Nano?
I have an old TFT display (extracted from an MP5 player) and I can't figure out how to connect it with an arduino nano, pls help.
here's the datasheet of the TFT:
http://read.pudn.com/downloads137/sourcecode/embed/586271/Varitronix-2.8-lcd/vl-ps-cog-t280mbqi-041.pdf
Thank you.

The datasheet says it all: A ILI9320 display driver with a 16-bit data bus (instead of SPI). Can you show a picture of the display and the connections? It's pretty close to https://learn.adafruit.com/adafruit-3-5-color-320x480-tft-touchscreen-breakout/8-bit-wiring-and-test. (8bit). If no 16-bit parallel driver is available you'll have to look at the ILI9320 datahseet and build one. However, if your objective is just to get a display for an Arduino, just buy a new well-known display with a simple SPI interface for which there are drivers.

Is this datasheet hosted on the end of a 56k dialup modem...?

The Nano isn't a good choice for driving that screen. You need almost all the pins of the Nano to connect to the screen alone, and there's not enough to include the touch-screen as well. And that's when you're not using the serial port of the Arduino (TX/RX pins) for communication with the PC.
You need to connect:

16 data pins
/CS pin
/RS pin
/WR pin
Optionally RD pin, or tie it to 3.3V
/RESET pin

And all those need to be level shifted to 3.3V.
You need to provide 3.3V to VCC1/2 and VCI.  The LED A connects to 5V (since it has more current capacity than the 3.3V) and each LED Kx pin through a suitable resistor (220Ω maybe) to ground.
The touchscreen needs the X- and Y- pins connecting to a digital IO pin, and the X+ and Y+ pins to analog IO pins that can also double as digital IO pins (so not A6/A7 on boards that have them).
And then you need to obtain or write the software to drive the ILI9320 through the 16-bit interface.
Driving the interface is simple enough:
Initially:

Set /CS HIGH
Set /WR HIGH
Set /RD HIGH (if not tied to 3.3V)
Set /RESET HIGH
Short delay
Set /RESET LOW
Short delay
Set /RESET HIGH

Then to transfer a group of 16-bit words:

Set /CS LOW
Set the value to write on the 16 data pins
Pulse /WR LOW then HIGH
Repeat from 2 for each word
Set /CS HIGH

Refer to the ILI9320 datasheet for how to control the chip, or use existing library code (does uTFT or u8glib support it?).
For the touch screen it's a case of setting Y- LOW and Y+ HIGH, and X- and X+ to INPUT, then reading the analog value from X+.  Repeat with X- set LOW and X+ set HIGH, and both Y set to INPUT, and read the analog value from Y+.
You can also get better results by reading multiple inverted settings:

Y- = LOW, Y+ = HIGH, X- = INPUT, Read X+.
Y- = HIGH, Y- = LOW, X- = INPUT, Read X+.
Subtract the second reading from 1023
Add the first and (modified) second reading
Divide by two.
Repeat for X-/X+ reading from Y+.

You can also take multiple readings and average them out to reduce noise and stabilise the output somewhat.
And of course on top of all that you need to find a way to connect to a 0.5mm pitch connector. Normally a 0.5mm pitch FPC socket is used, which means a PCB with one on.  You may be able to find 37 pin adaptor for it, but 37 pins isn't a common format.  Normally 50 pin is more common to accommodate a more general purpose interface including the M0-M2 pins that allow you to select the interface type, as well as an 18-bit data bus to allow full RGB6/6/6 interfacing, and even buffer-less clocking of raw display data for very high speed display updates by MCUs that support such an interface.

I'll try it later (can't do it now because my computer is toast), thank you for your help by the way. i'll tell you later if it worked.


text:
how to use mouse.h library for arduino uno
I want to use mouse.h library with arduino but mouse.h library only for Leonardo not UNO . How to use mouse.h for UNO if not
can we convert arduino UNO to Leonardo ?

The only way to use Mouse.h on an Arduino is to use it on a compatible Arduino. You cannot "convert" an Uno into a Leonardo, since you would have to not only replace the MCU on the board (with one that is SMD only), you would have to replace the PCB itself as well. I.e., throw away the Uno and replace it with a Leonardo.
The Mouse.h (and Keyboard.h) requires an MCU with a built-in USB interface, such as the ATMega32U4 that the Leonardo has. The ATMega328p does not have such an interface (note: the "U" in the name kind of gives it away...).
However, all is not lost.  The Uno does have a chip on it with a "U" in the name (as long as it's a genuine Arduino board and not a cheap Chinese clone with a CH340G chip).  That chip, used to interface the ATMega328p to the PC through USB, can be reprogrammed to look like different devices, however doing so can break your ability to then program the Arduino itself.
You can read more about hacking your Arduino to be a mouse here.


text:
Need help with an Arduino project using a RTC and LEDs
I need some help with a project I am doing involving the DS1307 RTC. I am trying to make what is essentially a way to mins quickly check the time which involves nine LEDs slowly lighting up every 10 so that I can quickly check time but looking at it. : So far I've tried TimeAlarms but I can't figure out how to do this. I have a Arduino Uno by the way.
Can someone possibly help?

start by learning how to light up the LEDs .... then learn how to use the  DS1307 RTC .... tutorials can be found on the web

please explain what slowly lighting up actually means

Use the SQW pin on the DS3231 or DS1307 to create 1sec pulse, read it on your Arduino. There are very good libraries are available (like RTClib from adafruit).


text:
Need help with using LED matrix with pushbuttons
I am building a small project that uses a pair of 8x8 LED matrix (driven by the MAX7219), a pair of SG90 servos, a HC-SR04 ultrasonic sensor, a 16x2 LCD (Hitachi HD44780 driver), some push buttons and all controlled with the Arduino Uno. All the components are powered using another usb port on my pc.
When I tried intergrating all the compenents, I noticed the LED matrix does not light up at all. I've decided to combine serveral basic code samples to test their interaction with eachother, where i noticed the use of pinMode to declare my pins for the push buttons will cause the LED matrix to stop working. Removing the section using // will get the led matrix(s) to work again.
Does anyone have any experience with this issue and can explain to me what causes this conflict? I've tried going through the LedControl documentation on the arduino page and I still could not understand what causes this issue.
/*

test build for debug

log:

LED Matrix : test code added, no issues
LCD Display: test code added, no issues
Sensor: test code added, serial clashed with LED Matrix. Working with disabled serial, Main build still not resolved.
Servo: test code added, no issues
Buttons: test code added, LED Matrix no longer light up. issue appears to be at the (pinMode) section when declaring buttons as inputs.

*/

//buttons

#include <Button.h>

const int positiveButtonPin = A1;
 int positiveButtonState = LOW;

const int negativeButtonPin = A2;
 int negativeButtonState = LOW;

// servo library setup
#include <Servo.h>
Servo servo1;
Servo servo2;

// lcd setup
#include <LiquidCrystal.h>
const int rs = 12, en = 11, d4 = 10, d5 = 9, d6 = 8, d7 = 7;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

//led matrix library setup
#include "LedControl.h"
LedControl lc=LedControl(2,1,0,2);  // Pins: DIN,CLK,CS, # of Display connected
unsigned long delayTime=200;  // Delay between Frames

// sensor setup
const int trigPin = 6;
const int echoPin = 5;
long duration;
int distance;

// led matrix arrays (test with 2 formats)

byte invader1a[] = {0x7C,0x7C,0x60,0x7C,0x7C,0x60,0x7C,0x7C};

byte invader1b[] = {0x78,0x7C,0x66,0x66,0x66,0x66,0x7C,0x78};

byte invader2a[] =
{
  B00100100, // First frame of invader #2
  B00100100,
  B01111110,
  B11011011,
  B11111111,
  B11111111,
  B10100101,
  B00100100
};

byte invader2b[] =
{
  B00100100, // Second frame of invader #2
  B10100101,
  B11111111,
  B11011011,
  B11111111,
  B01111110,
  B00100100,
  B01000010
};

void setup() {
  // put your setup code here, to run once:

//button setup
{
//  pinMode(positiveButtonState, INPUT);                    //         <----------------- THIS CAUSES ISSUE WITH LED MATRIX
//  pinMode(negativeButtonState, INPUT);
}

// servo setup
  servo1.attach(4);
  servo2.attach(3);

//sensor serial test code
// sensor setup
  pinMode(trigPin, OUTPUT); // Sets the trigPin as an Output
  pinMode(echoPin, INPUT); // Sets the echoPin as an Input
//  Serial.begin(9600);                                         //     <----------------- THIS CAUSES ISSUE WITH LED MATRIX, DISABLED

    //led matrix setup
  lc.shutdown(0,false);  // Wake up displays
  lc.shutdown(1,false);
  lc.setIntensity(0,2);  // Set intensity levels
  lc.setIntensity(1,2);
  lc.clearDisplay(0);  // Clear Displays
  lc.clearDisplay(1);

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

}

//  Creating array strings

void sinvader1a()
{
  for (int i = 0; i < 8; i++)
  {
    lc.setRow(0,i,invader1a[i]);
  }
}

void sinvader1b()
{
  for (int i = 0; i < 8; i++)
  {
    lc.setRow(0,i,invader1b[i]);
  }
}

void sinvader2a()
{
  for (int i = 0; i < 8; i++)
  {
    lc.setRow(1,i,invader2a[i]);
  }
}

void sinvader2b()
{
  for (int i = 0; i < 8; i++)
  {
    lc.setRow(1,i,invader2b[i]);
  }
}

void loop() {
  // put your main code here, to run repeatedly:

//servo test code
    // servo attach
    servo1.attach(4);
    servo2.attach(3);

     servo1.write (120);  // change angle here below. adjust until it looks like it's looking at user
  servo2.write (90);
  delay(250);
  servo1.write (90);
  servo2.write (120);
  delay(250);
// servo detach to reduce noise
servo1.detach();
servo2.detach();

// led matrix test code
    sinvader1a();
    delay(delayTime);
    sinvader2a();
    delay(delayTime);

    sinvader1b();
    delay(delayTime);
    sinvader2b();
    delay(delayTime);

    //lcd hello world code
    // set the cursor to column 0, line 1
      // (note: line 1 is the second row, since counting begins with 0):
      lcd.setCursor(0, 1);
      // print the number of seconds since reset:
      lcd.print(millis() / 1000);

//sensor test code
// Clears the trigPin
digitalWrite(trigPin, LOW);
delayMicroseconds(2);

// Sets the trigPin on HIGH state for 10 micro seconds
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
duration = pulseIn(echoPin, HIGH);
distance= duration*0.034/2;

// no longer useful due to disabled serial
/*
if (distance<1000){
Serial.print("Distance: ");
Serial.println(distance);}
else {}
*/

}

please reduce your code to the minimal amount of code that still exhibits the undesired behaviour.

Consider the basic USB port is only required to supply 500mA.  It should be expected that a computer, to protect its self, would reduce the USB voltage if this current limit was violated.  2. All Arduino libraries are not compatible with one another.  Unless the library author was kind enough / thorough enough to document what hardware is used, the only way to tell is to look at the library source code.

You also did not specify which Arduino you were using.

It appears you are attempting to use the hardware UART for both talking to your MAX7221 or MAX7219:
LedControl lc=LedControl(2,1,0,2);

And for talking to, maybe, the SDK's serial monitor:
Serial.begin(9600);

There is only 1 UART on the Atmel processor used on an Arduino Uno.  Consider using a larger Arduino / processor where there are more UARTs on the processor.  Be aware that it may be necessary to re-write the library to use the alternative hardware on larger processors.
Also, there is an error in your code and it is causing you to think about it incorrectly:
The lines:
pinMode(positiveButtonState, INPUT);
pinMode(negativeButtonState, INPUT);

...interfere with the LED matrix because they are changing pin zero from a UART Receive to a GPIO Receive.  Likely you meant to type:
pinMode(positiveButtonPin, INPUT);
pinMode(negativeButtonPin, INPUT);