text:
Undocumented industrial servo with 8-wire encoder: how to read this encoder?
I have scavenged an industrial servo with its attached ballscrew linear actuator from an old large format scanner, and I am trying to figure out how to make a 'servo drive' aka 'servo driver' aka 'servo controller'.
I'm a total novice at arduino, and am mostly a copy/paste coder - so of course this makes my goal harder.
I can find a lot of information on how to read a simple AB offset encoder that needs four wires to work, but the encoder I have has eight wires:
A+, A-, B+, B-, Z+, Z-, +5v, 0v(aka GND)
With +5v supplied to it's wire and GND connected to 0v, rotating the motor shaft by hand, my meter reads:

A+: +3.97v as the 'high' and +.036v as 'low'
A-: same
B+: same
B-:    same
Z+: same - but only goes high at one location on the 360 degree
 rotation
Z-: same - but only goes high at one location on the 360 degree
rotation - the same location as Z+

NOTE: Both Z pulses coincide with pulses on A+, B+, and B- ... but those are NOT coincident on A-. So maybe A- has the Z+/- trigger in it's place? I don't know. It was VERY challenging to stop rotating the shaft AT a pulse because of the tiny size of the divisions.
All voltages seen by my digital multimeter were positive voltages.
I do not understand how to properly use the encoder with so many wires. I can sort of understand that the positive and negative are probably opposite signals from each other, sort of error protection or something? I know that the Z= and Z- are roattion counters at either 90, 180, or some other offset angle to allow ticking full rotations. But am unsure about this all and am reading a lot of material that is beyond me. I'm stumped.
I can install the following code on an UNO and the UNO reads the encoder just fine off the A+ and B+ lines, with increasing count for one direction of rotation and decreasing count for the other direction. So it is reflecting the movement as it should...
BUT- I am getting 8000 pulses per shaft revolution rather than the 2000 pulses per revolution in the documentation. So something's not right here. I should see 2000 pulses per revolution... is this because of the lack of use of the other wires? Or something else?
Code i'm using for just A+ and B+:
    /*
*Quadrature Decoder
*/
#include "Arduino.h"
#include <digitalWriteFast.h>

// Quadrature encoders
// Left encoder
#define c_LeftEncoderInterruptA 0
#define c_LeftEncoderInterruptB 1
#define c_LeftEncoderPinA 2
#define c_LeftEncoderPinB 3
#define LeftEncoderIsReversed

volatile bool _LeftEncoderASet;
volatile bool _LeftEncoderBSet;
volatile bool _LeftEncoderAPrev;
volatile bool _LeftEncoderBPrev;
volatile long _LeftEncoderTicks = 0;

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

  // Quadrature encoders
  // Left encoder
  pinMode(c_LeftEncoderPinA, INPUT);      // sets pin A as input
  digitalWrite(c_LeftEncoderPinA, LOW);  // turn on pullup resistors
  pinMode(c_LeftEncoderPinB, INPUT);      // sets pin B as input
  digitalWrite(c_LeftEncoderPinB, LOW);  // turn on pullup resistors
  attachInterrupt(c_LeftEncoderInterruptA, HandleLeftMotorInterruptA, CHANGE);
  attachInterrupt(c_LeftEncoderInterruptB, HandleLeftMotorInterruptB, CHANGE);
}

void loop()
{
  Serial.print("Encoder Ticks: ");
  Serial.print(_LeftEncoderTicks);
  Serial.print("  Revolutions: ");
  Serial.print(_LeftEncoderTicks/2000.0); //2000 Counts Per Revolution, per the engineering manual
  Serial.print("\n");
}

// Interrupt service routines for the left motor's quadrature encoder
void HandleLeftMotorInterruptA(){
  _LeftEncoderBSet = digitalReadFast(c_LeftEncoderPinB);
  _LeftEncoderASet = digitalReadFast(c_LeftEncoderPinA);

  _LeftEncoderTicks+=ParseEncoder();

  _LeftEncoderAPrev = _LeftEncoderASet;
  _LeftEncoderBPrev = _LeftEncoderBSet;
}

// Interrupt service routines for the right motor's quadrature encoder
void HandleLeftMotorInterruptB(){
  // Test transition;
  _LeftEncoderBSet = digitalReadFast(c_LeftEncoderPinB);
  _LeftEncoderASet = digitalReadFast(c_LeftEncoderPinA);

  _LeftEncoderTicks+=ParseEncoder();

  _LeftEncoderAPrev = _LeftEncoderASet;
  _LeftEncoderBPrev = _LeftEncoderBSet;
}

int ParseEncoder(){
  if(_LeftEncoderAPrev && _LeftEncoderBPrev){
    if(!_LeftEncoderASet && _LeftEncoderBSet) return 1;
    if(_LeftEncoderASet && !_LeftEncoderBSet) return -1;
  }else if(!_LeftEncoderAPrev && _LeftEncoderBPrev){
    if(!_LeftEncoderASet && !_LeftEncoderBSet) return 1;
    if(_LeftEncoderASet && _LeftEncoderBSet) return -1;
  }else if(!_LeftEncoderAPrev && !_LeftEncoderBPrev){
    if(_LeftEncoderASet && !_LeftEncoderBSet) return 1;
    if(!_LeftEncoderASet && _LeftEncoderBSet) return -1;
  }else if(_LeftEncoderAPrev && !_LeftEncoderBPrev){
    if(_LeftEncoderASet && _LeftEncoderBSet) return 1;
    if(!_LeftEncoderASet && !_LeftEncoderBSet) return -1;
  }
}

.
.
.
Can someone explain the function of, and how to use, all eight wires? Explain why I'm getting 4X the counts that I should with that code above? PLEASE?
.
.
.
I'm posting images of the pages from the machine's engineering handbook that have info about the servo and encoder. The info there shows that it was more or less controlled like an RC servo from the mainboard's perspective - just PWM. But it had the drive/driver/controller parts right on the mainboard of the machine.
If it will be of use I can post pictures of the encoder board itself, but at this point I did not think that necessary.

connect +5V and GND to the encoder ... use a voltmeter to monitor one output pin ... turn servo slowly by hand

Wire identity is already established. See picture posted of pinout table.

if that is true, then why does your post have the following statement? ... positive and negative are probably opposite signals from each other, sort of error protection or something

I put that in my post because I have read a few web pages that say that this is how some encoders work. And you didn't quote the question mark immediately following the word 'something". I have added voltage readings for all wires to the question.

I had some trouble figuring this out too.
I did some more googling and found this site below via an Arduino forum post:
8 wire connection for quadrature encoder, differential wiring
Here is what they say:

"These terms refer not to the waveforms of signals, but instead to the way the signals are wired.
Single-ended wiring uses one signal wire per channel and all signals are referenced to a common ground.
TTL and Open Collector are types of single-ended wiring.
Differential wiring uses two wires per channel that are referenced to each other. The signals on these wires are always 180 electrical degrees out of phase, or exact opposites. This wiring is useful for higher noise immunity, at the cost of having more electrical connections. Differential wiring is often employed in longer wire runs as any noise picked up on the wiring is common mode rejected."

So basically we have our Power supply wire and ground, and 2 wires per signal (A+/A-, B+/B-, Z+/Z-).
2 + 6 wires = 8 wires
Now all I have to figure out is how to connect those 6 wires to an Arduino. I get how to connect the A+, B+, Z+ signals on 3 interrupt pins, now I'm just wondering if the other 3 (A-, B-, Z-) should be connected to 3 more interrupt pins.

The differential signals should be connected to a differential amplifier or an instrumentation amplifier. The amplifier will give a single output that can be connected to the Arduino via galvanic isolation.

You have already found out, how the encoder works (basically like any other rotary encoder, only with more outputs for different angle values). That is great work.
You get a value 4 times as big because of 2 little mistakes:

When you use attachInterrupt(), you set it to trigger on a CHANGE of the line. One pulse consists of 2 changes (for example LOW to HIGH and then HIGH to LOW). So the interrupt get's triggered twice per encoder pulse. That's a factor of 2 for the resulting value.
You attach an interrupt to both of the lines, but both lines output one pulse per one encoder tick. So the value get's incremented twice per tick, what means another factor of 2. You only need an interrupt on one of the lines. The other line is only there to indicate the direction of the rotation. When the interrupt for the first line triggers, you should check the value of the second line. If it is HIGH, the encoder is rotating in one direction. If it is LOW, it rotates in the oposite direction. The lines are internally connected to little buttons/switches, that are fixed to the casing with a little offset between then. They get activated by little nubs, that are connected to the axis. Depending on from which direction the nub comes during a rotation, the first or the second button/switch will get activated first. A little after that, also the second switch will activate. So you can monitor one line, and if a pulse starts on it, you check if there already is a pulse on the other line. If yes, the other line was activated first.

So all in all this results in the factor 4 in the encoder results.

Note, that your ParseEncoder() function is a little redundant and overcomplicated. In the inner if statements you check for some values, that cannot happen in there because of the outer if statement. But this function will reduce itself to simply one if statement (or less, if you use the value directly without if), since with the above, you only need to check the value of 1 line.

OK - learning that quadrature encoding can be read as 1x, 2x, or 4x per rotor mark is not the same as learning how this particular encoder works. Using A+ and B+ I count all four possible ticks as a rotor mark passes. Z+ would theoretically let me count full rotations and serve as a check against missed triggers by the A+ interrupt - if I could figure out how to interrupt interrupts because Z+ rises at the same time that A+ rises. Got it. But A- and B- and Z- remain unexplained/not understood. Not that I MUST use them, but I do want to understand what they are there for if I can.

Unfortunately I cannot help you with undocumented hardware, as I cannot test it myself. You yourself have to analyse how the outputs behave. If you make a diagram, how exactly the outputs behave, I can try to guess the function, but not more.

Fair enough. My assumption (and reason for posting) was that someone here in the stack would read "8 wire encoder" and then read my reported voltages .. and be familiar with similar encoders enough to illuminate me on what the other wires are for and maybe even how to use them. I still have a sneaking suspicion they are a redundancy to error-check with but can't be sure with my almost non-existent knowledge of these things.

Still hoping someone will explain the other three wires: A-, B-, and Z-. Can't mark this answer as the answer without having the first part of the question addressed.


text:
DHT11 sensor reporting all null values
I am using a DHT11 sensor attached to a NodeMCU ESP8266 to have a web server reporting the local humidity and temperature values. I don't have a resistor attached in the circuit, the DHT11 is directly connected to the NodeMCU board. Till yesterday, the setup was giving me correct values, but from today morning, I am getting all nulls from the sensor. Does this mean that the sensor is dead? Should I have had a resistor attached to the circuit to prevent this, or does that not make any difference?
EDIT:
Please consider my question before negative voting me. I considered this question:
Problem with a DHT11 Temperature & Humidity sensor
I have followed the circuit diagram as given in the following page:
https://www.electronicwings.com/nodemcu/dht11-sensor-interfacing-with-nodemcu
It's just that I am using a NodeMCU istead of an Arduino. Does that make my question unworthy of posting here? The problem is similar.

From your question it's not clear if you have the pure (blue) DHT11 sensor or a module with the 4pin sensor mounted on a small pcb with only 3 pins. (The only difference between the sensor and module is that the module will have a filtering capacitor and pull-up resistor inbuilt, and for the sensor, you have to use them externally if required.). Without measuring or swapping with a replacement known to function it's a guessing game.

Hi @LotPings, I have the 4 pin sensor, I have followed the circuit diagram as provided in the following page: https://www.electronicwings.com/nodemcu/dht11-sensor-interfacing-with-nodemcu

source: Stack Exchange

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

sort: votes


text:
How to scale a bitmap (uint8_t array) in Arduino?
So I have a project where I send text to an Arduino, which is then printed out as a QR code on a thermal printer that can take a bitmap image with a given width and height.
Is there a way I can "scale up" the "image," making it so one pixel is scaled up to 4 or 8 pixels?
Additionally, would it be possible to add a "quiet zone" of sorts on the left side of the image, as I am not able to offset/justify it to the middle.
QR Code lib: https://github.com/ricmoo/QRCode
Thermal printer lib: https://github.com/adafruit/Adafruit-Thermal-Printer-Library

Trying to splice in the QRPrint library causes the ESP32 to crash over and over.

Which Arduino? Most of them wouldn't have enough RAM for that.

@NickGammon I am using an ESP32, which has an Arduino core. :)

You didn't tell use the size of your QRCode, nor the type of Arduino you
are using. So I am just going to guess that your problem is that you may
have enough RAM to store the raw QRCode, but not enough to store a
scaled bitmap version.
The Adafruit tutorial for their thermal printer library suggests
printing bitmaps with the method:
printBitmap(width, height, tablename)

where tablename is an array holding the bitmap data. This will
obviously not work if you don't have enough RAM to store the array.
Fortunately, there is an overloaded method:
void Adafruit_Thermal::printBitmap(int w, int h, Stream *fromStream)

that allows you to stream the image data instead of preparing it in RAM.
You can create a stream that delivers arbitrary data by writing a class
that derives from Stream. Here is a tentative, untested
implementation, that delivers a scaled-up QRCode one pixel at a time:
// Stream a scaled QRCode one pixel at a time.
class QRCodeStream : public Stream
{
public:
    QRCodeStream(const QRCode &code, uint8_t scale = 1)
    : qrcode(code), scale(scale) {}

    // Output: writing to this stream is a no-op.
    size_t write(uint8_t) {}
    void flush() {}

    // Input delivers the QRCode pixels.
    int available();
    int peek();
    int read();
private:
    QRCode &qrcode;
    uint8_t scale;
    bool done = false;
    uint8_t code_x = 0;  // coordinates of the QRCode module
    uint8_t code_y = 0;
    uint8_t pix_x = 0;  // pixel coordinates within the module
    uint8_t pix_y = 0;
};

int QRCodeStream::available()
{
    // For simplicity, pretend the bytes come one at a time.
    if (done) return 0;
    else return 1;
}

int QRCodeStream::peek()
{
    if (done) return -1;
    if (qrcode_getModule(&qrcode, code_x, code_y)) {
        return 0;  // black
    } else {
        return 255;  // white
    }
}

int QRCodeStream::read()
{
    if (done) return -1;
    int data = peek();

    // Move to the next pixel.
    if (++pix_x >= scale) {
        pix_x = 0;
        if (++code_x >= qrcode.size) {
            code_x = 0;
            if (++pix_y >= scale) {
                pix_y = 0;
                if (++code_y >= qrcode.size) {
                    done = true;
                }
            }
        }
    }

    return data;
}

This would be used as
printer.printBitmap(width, height, QRCodeStream(qrcode, scale));

Note that QRCodeStream delivers the image data as 8-bit gray scale,
where each pixel is returned as one byte, either 0 (for black) or 255
(for white). This is likely not the format expected by the thermal
printer library, which seems to expect 1-bit black and white data, with
8 pixels packed in each byte. You will have to adapt the code for
the right format, which will likely be tedious, but not overly complex.
I leave that “as an exercise to the reader”.

Apologies. I am using an ESP32, and the Arduino IDE reports a Max Mem of 327680 bytes.
And I am aiming for a Version 3 QR Code at minimum :)

And here is the results of scales 1-3: https://i.imgur.com/7gBl0c1.jpg - Not sure if it's due to the format of the code itself, or something else...

@TonySesek: Looks like it's working, but every pixel gets converted to a line of 8 pixels because of the 1-bit vs. 8-bits format difference.

Ohh, my brain skipped over the important part of your postscript, my bad. Alright, that shouldn't be too bad. Maybe I can make another stream to take the stream, haha.

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


text:
ESP8266 WiFi.begin() isn't working
I did a project for IoT attendance system using ESP8266 and RDM6300. However, I can connect to wifi using WiFiMulti.addAP() function for my home WiFi.
I tried WiFi.begin() instead of WiFiMulti.addAP() function to connect to my mobile hotspot but the esp8266 is failing to connect. In fact, WiFi.begin() also failed to connect to the same wifi router which was previously connected by WiFiMulti.addAP(). Serial monitor constantly showing the below error.
Exception (3):
epc1=0x4020970d epc2=0x00000000 epc3=0x00000000 excvaddr=0x4003bfc9 depc=0x00000000

>>>stack>>>

ctx: cont
sp: 3ffffbc0 end: 3fffffc0 offset: 01a0
3ffffd60:  00000000 00000004 3ffffe40 3ffffef0
3ffffd70:  4010156c 0000049c 000003fd 40209837
3ffffd80:  0000049c 00001000 000003fd 4010156c
3ffffd90:  40106980 3ffe85ad 3ffffe40 402354f1
3ffffda0:  401004a5 402355db 3fff0c1c 0000049c
3ffffdb0:  000003fd 3ffffef0 3fff0c1c 402355be
3ffffdc0:  ffffff00 55aa55aa 00000035 00000020
3ffffdd0:  00000020 00000048 0000004a aa55aa55
3ffffde0:  000003ff 40235aa8 3fff0c1c 3fff0c1c
3ffffdf0:  000000ff 3fff0c1c 0000049c 00000000
3ffffe00:  401004a5 00000001 3fff0c2c 40235cc2
3ffffe10:  00000008 3fff0c1c 000000ff 3ffffef0
3ffffe20:  3fffff10 3fff0c53 00000035 00000020
3ffffe30:  3fff0cdc 3fffff51 00000001 40235d72
3ffffe40:  3ffffef0 40242be0 00000000 0000000c
3ffffe50:  3fff101c 3fffff10 3fff6f54 40235d41
3ffffe60:  3fff0c1c 40235da8 3ffe84dc 3ffe85ae
3ffffe70:  402019ca 3ffe85ae 3ffe85b3 40201927
3ffffe80:  61666152 00000074 3ffffe60 40204666
3ffffe90:  4000e243 00000030 3ffffe60 402046c4
3ffffea0:  616d7374 2e2e3730 3ffffe00 40204901
3ffffeb0:  3ffffdf0 0693b740 000035af fffffffe
3ffffec0:  00000090 3fffc6fc 00000003 40201dd4
3ffffed0:  3ffee50c 000000f2 000000f2 40206bf8
3ffffee0:  8ab9b001 00a0a64e 00000000 40206057
3ffffef0:  78666152 3fff0c00 0000049c 00000000
3fffff00:  00000a2e 0000007f 3fff0c1c 402356c6
3fffff10:  61666172 66617274 32317461 40209500
3fffff20:  00000001 3fff0c1c 00000000 402099e8
3fffff30:  000003fd 402351a3 00000000 40101538
3fffff40:  00000001 001ce8e7 3ffeea78 402351be
3fffff50:  40235100 00000001 00000081 00000002
3fffff60:  00000004 00000000 3ffee544 00000001
3fffff70:  402083ea 000003e8 000003e8 3ffee870
3fffff80:  3ffee544 00000000 3ffee750 40201194
3fffff90:  00000000 00000000 ffefeffe feefeffe
3fffffa0:  3fffdad0 00000000 3ffee840 40207830
3fffffb0:  feefeffe feefeffe 3ffe8520 40101809
<<<stack<<<

ets Jan  8 2013,rst cause:2, boot mode:(3,6)

load 0x4010f000, len 1384, room 16
tail 8
chksum 0x2d
csum 0x2d
v8b899c12
~ld

this is the code I uploaded to ESP8266:

#include <Arduino.h>

#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>

#include <ESP8266HTTPClient.h>

#include <WiFiClient.h>

#include <rdm6300.h>

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels

// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);

#define RDM6300_RX_PIN 2
#define READ_LED_PIN 14

ESP8266WiFiMulti WiFiMulti;
Rdm6300 rdm6300;

String RFID[] = {"5958666", "5958741"};

String SID[] = {"161-115-123", "161-115-124"};

String NAME[] = {"Rafat", "Saney"};

int flag[2] = {0, 0};

void setup() {

  Serial.begin(115200);
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
  pinMode(READ_LED_PIN, OUTPUT);
  digitalWrite(READ_LED_PIN, LOW);
  rdm6300.begin(RDM6300_RX_PIN);

  Serial.println();
  Serial.println();
  Serial.println();
  OLED("Connecting...");
  for (uint8_t t = 4; t > 0; t--) {
    Serial.printf("[SETUP] WAIT %d...\n", t);
    Serial.flush();
    delay(1000);
  }

  WiFi.mode(WIFI_STA);
  WiFi.begin("custom", "customjack.xyz");
  Serial.print("Connecting");

  while (WiFi.status() != WL_CONNECTED) {
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("Connected");
  OLED("Connected");
  Serial.println(WiFi.localIP());

}

void loop() {
  // wait for WiFi connection
  if ((WiFi.status() == WL_CONNECTED)) {
label:
    OLED("Place Your ID");
    String tag;
    int check = 0;
    if (rdm6300.update())
    {
      tag = String(rdm6300.get_tag_id());
      Serial.println(tag);
      for (int i = 0; i < 1; i++)
      {
        if (RFID[i] == tag) // checking validity of RFID
        {
          tone(READ_LED_PIN, 392);
          delay(100);
          noTone(READ_LED_PIN);
          check = 1;
          if (flag[i] == 1) // Flag=1 meaans already attendance counted
          {
            Serial.println("Attendance Already Counted");
            OLED("Already Counted");
            delay(2000);
            goto label;
          }
          OLED("Welcome "+NAME[i]);
          flag[i] = 1;
          WiFiClient client;
          HTTPClient http;

          Serial.print("[HTTP] begin...\n");
          String url = "http://metrounisas.000webhostapp.com/action.php?ID=" + SID[i];
          if (http.begin(client, url ) ) { // HTTP

            Serial.print("[HTTP] GET...\n");
            // start connection and send HTTP header
            int httpCode = http.GET();

            // httpCode will be negative on error
            if (httpCode > 0) {
              // HTTP header has been send and Server response header has been handled
              Serial.printf("[HTTP] GET... code: %d\n", httpCode);

              // file found at server
              if (httpCode == HTTP_CODE_OK || httpCode == HTTP_CODE_MOVED_PERMANENTLY) {
                String payload = http.getString();
                Serial.println(payload);
              }
            } else {
              Serial.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode).c_str());
            }

            http.end();
          } else {
            Serial.printf("[HTTP} Unable to connect\n");
          }
        }
      }
      if (check == 0) {
        tone(READ_LED_PIN, 261);
        noTone(READ_LED_PIN);
        Serial.println("Invalid RFID");
        OLED("INVALID ID");
        delay(2000);
      }
    }
  }

  delay(1000);
}

void OLED(String txt){
  display.clearDisplay();
  display.setTextSize(1);
  display.setTextColor(WHITE,BLACK);
  display.setCursor(30, 30);
  display.println(txt);
  display.display();
  delay(2000);
}

how is it powered?

It's getting powered from PC with micro-USB cable

esp8266 can't get power from USB. you have a development board with esp8266? but then the powering should be OK


text:
Why do I see error in this code
NewPing sonar(TRIG_PIN, ECHO_PIN, MAX_DISTANCE);

AF_DCMotor motor1(1, MOTOR12_1KHZ);
AF_DCMotor motor2(2, MOTOR12_1KHZ);
AF_DCMotor motor3(3, MOTOR34_1KHZ);
AF_DCMotor motor4(4, MOTOR34_1KHZ);
Servo myservo;

boolean goesForward=false;
int distance = 100;
int speedSet = 0;

void setup() {

  myservo.attach(10);
  myservo.write(115);
  delay(2000);
  distance = readPing();
  delay(100);
  distance = readPing();
  delay(100);
  distance = readPing();
  delay(100);
  distance = readPing();
  delay(100);
}

void loop() {
 int distanceR = 0;
 int distanceL =  0;
 delay(40);

 if(distance<=15)
 {
  moveStop();
  delay(100);
  moveBackward();
  delay(300);
  moveStop();
  delay(200);
  distanceR = lookRight();
  delay(200);
  distanceL = lookLeft();
  delay(200);

  if(distanceR>=distanceL)
  {
    turnRight();
    moveStop();
  }else
  {
    turnLeft();
    moveStop();
  }
 }else
 {
  moveForward();
 }
 distance = readPing();
}

int lookRight()
{
    myservo.write(50);
    delay(500);
    int distance = readPing();
    delay(100);
    myservo.write(115);
    return distance;
}

int lookLeft()
{
    myservo.write(170);
    delay(500);
    int distance = readPing();
    delay(100);
    myservo.write(115);
    return distance;
    delay(100);
}

int readPing() {
  delay(70);
  int cm = sonar.ping_cm();
  if(cm==0)
  {
    cm = 250;
  }
  return cm;
}

void moveStop() {
  motor1.run(RELEASE);
  motor2.run(RELEASE);
  motor3.run(RELEASE);
  motor4.run(RELEASE);
  }

void moveForward() {

 if(!goesForward)
  {
    goesForward=true;
    motor1.run(FORWARD);
    motor2.run(FORWARD);
    motor3.run(FORWARD);
    motor4.run(FORWARD);
   for (speedSet = 0; speedSet < MAX_SPEED; speedSet +=2) // slowly bring the speed up to avoid loading down the batteries too quickly
   {
    motor1.setSpeed(speedSet);
    motor2.setSpeed(speedSet);
    motor3.setSpeed(speedSet);
    motor4.setSpeed(speedSet);
    delay(5);
   }
  }
}

void moveBackward() {
    goesForward=false;
    motor1.run(BACKWARD);
    motor2.run(BACKWARD);
    motor3.run(BACKWARD);
    motor4.run(BACKWARD);
  for (speedSet = 0; speedSet < MAX_SPEED; speedSet +=2) // slowly bring the speed up to avoid loading down the batteries too quickly
  {
    motor1.setSpeed(speedSet);
    motor2.setSpeed(speedSet);
    motor3.setSpeed(speedSet);
    motor4.setSpeed(speedSet);
    delay(5);
  }
}

void turnRight() {
  motor1.run(FORWARD);
  motor2.run(FORWARD);
  motor3.run(BACKWARD);
  motor4.run(BACKWARD);
  delay(500);
  motor1.run(FORWARD);
  motor2.run(FORWARD);
  motor3.run(FORWARD);
  motor4.run(FORWARD);
}

void turnLeft() {
  motor1.run(BACKWARD);
  motor2.run(BACKWARD);
  motor3.run(FORWARD);
  motor4.run(FORWARD);
  delay(500);
  motor1.run(FORWARD);
  motor2.run(FORWARD);
  motor3.run(FORWARD);
  motor4.run(FORWARD);
}

Because you didn't include the libraries maybe? What is the error you see?

You asked about "this error", but you didn't include the actual error message

All of the errors I got were "NewPing does not name a type", "AF_DCMOtor does not name a type" and "motor<> was not declared in this scope". I don't see library includes; at least one for NewPing is needed. I don't know where AF_DCMotor is supposed to be declared but, as it is not declared as a type, it leaves all of the motor undefined. Those are the bulk (if not all) of the errors as the code stands now. Add the missing NewPing library do whatever you need to to define AF_DCMotor.

AF_DCMotor is also a library.

Makes perfect sense...

It probably needs a library. Looks like you have some kind of AFDC library and did not use it.


text:
How long should TinyMPU6050.h calibration run for?
I just found a lightweight library for the MPU6050 gyro. Example below.
mpu.Calibrate() never seems to end. I'm keeping it very still. When I take this out, the rest of the code works fine.
https://github.com/gabriel-milan/TinyMPU6050/blob/master/examples/ArduinoIDE_All_Gets_Example/ArduinoIDE_All_Gets_Example.ino

I feel so sorry about the previous releases of TinyMPU6050. I've just released v0.5.0 that shall soon be available at the Arduino Library Manager index.
The calibration method indeed was messy, so I decided to keep it simple. I also removed dependencies of String objects and Serial stuff and it seems to work pretty fine now.
If you keep having issues with that, please let me know!
The official link to release 0.5.0 follows:
https://github.com/gabriel-milan/TinyMPU6050/releases/tag/0.5.0


text:
Powering Moisture sensor via arduino pin
Can someone help me. I have this sensor
I just connected it to the 3V pin of my arduino only I read online that its better to connect it to a Arduinopin for power so you can put it off when not measuring. How do I do this? Can I just connect it to, let's say D4 and put this to HIGH and LOW or do I need something more. I googled a bit but found all kinds of different solutions. Some even talked about the need to PULLUP and PULLDOWN. whats the best way to do this.

If the sensor draws less than about 20mA when running then yes, you can just power it from any GPIO pin and set it HIGH for on or LOW for off. If you need more than about 20mA then you will need to switch the power with a transistor.

Thnx :). How do I find out how much mA it draws? its not on the board itself.

RTFM. If it's not in the FM then RTFM for the major component(s). (F = Fine :p )

The entire circuit board, including the LM393, power light and it's resistor, uses 2.2 mA at 3.3 VDC (4.12 mA at 5 VDC). Once the comparator is "triggered", the "D0-LED" and it's associated resistor come in to play which bumps the current up to 3.6 mA at 3.3 VDC (7.82 mA at 5 VDC).
I think it would be OK to use digitalWrite(pin_number, HIGH) to power the circuit board, then use digitalWrite(pin_number, LOW) to turn the power off.

Where did you find the specs? And do you read Dutch?

I used a DVOM with a variable output power supply to test one of the boards. This "voltage comparator board" is a common "addition" to several different moisture / rain sensors available on Aliexpress, Ebay, Amazon, etc. I don't read, write, or understand Dutch.

It worked. It gave lower numbers but I'm making % out of them anyway. thnx :)


text:
Waking an ESP8266 from Light-Sleep using a signal from MQTT?
I was wondering if it would be possible to wake an ESP8266 from a request over MQTT while it is in Light-Sleep mode? I am planning to implement a smart switch that would receive messages from a Raspberry Pi to turn off and on, however, I don't want to have to manually hit a button to trigger an external reset (I've seen this done in many examples already). I also don't think it would be efficient for me to just set a timer and have the ESP wake up in intervals. For instance, if I want to have the smart switch turn on an appliance and the PI sends a request over MQTT when the ESP is sleeping... this will do me no good. Curious if anyone has run into this issue before and what recommendations you have.

I was wondering if it would be possible to wake an ESP8266 from a request over MQTT while it is in Light-Sleep mode?

No. The ESP8266 has to be awake to communicate with the MQTT server.
The best you can hope for is a periodic wakeup to connect to the server and check for any new data.  But of course that relies on the data being set to QOS 2 so it keeps trying to be delivered until the ESP8266 is awake to receive it.


text:
Fonts/Org_01.h: No such file or directory
I have written one Arduino code for working with tft lcd 2.4 and  in it i used <Fonts/Org_01.h> new font ,It was working in my Win8 OS but now in Linux OS i have installed new Arduino in my Linux OS and in this Arduino i have get this error:

exit status 1 Fonts/Org_01.h: No such file or directory

the entire codes are shown blown:

#include <Adafruit_GFX.h>    // Adafruit's core graphics library
#include <Adafruit_TFTLCD.h> // Adafruit's hardware-specific library
#include <TouchScreen.h>     //Touchscreen library
#include <Fonts/Org_01.h>    //Include a different font
#include <EEPROM.h>         //Include the EEPROM library to score the highscore
#include <MCUFRIEND_kbv.h>
MCUFRIEND_kbv tft;

#include <TimeLib.h>

bool backsensed = false;
bool resetsensed = false;

// most mcufriend shields use these pins and Portrait mode:
uint8_t YP = A1;  // must be an analog pin, use "An" notation!
uint8_t XM = A2;  // must be an analog pin, use "An" notation!
uint8_t YM = 7;   // can be a digital pin
uint8_t XP = 6;   // can be a digital pin

#define TS_MINX 100
#define TS_MINY 120
#define TS_MAXX 920
#define TS_MAXY 940
//Create the touchscreen object
TouchScreen ts = TouchScreen(XP, YP, XM, YM, 300);  //(data,data,data,data,sensitivity);

//Some of the tft pins
#define LCD_CS A3
#define LCD_CD A2
#define LCD_WR A1
#define LCD_RD A0
// Optional, used to reset the display
#define LCD_RESET A4

#define REDBAR_MINX 80
#define GREENBAR_MINX 130
#define BLUEBAR_MINX 180
#define BAR_MINY 30
#define BAR_HEIGHT 250
#define BAR_WIDTH 30

//Create the tft object
//Adafruit_TFTLCD tft(LCD_CS, LCD_CD, LCD_WR, LCD_RD, LCD_RESET);

// Define some TFT readable colour codes to human readable names
#define BLACK   0x0000
int BLUE = tft.color565(50, 50, 255);
#define DARKBLUE 0x0010
#define VIOLET 0x8888
#define RED     0xF800
#define GREEN   0x07E0
#define CYAN    0x07FF
#define MAGENTA 0xF81F
#define YELLOW  0xFFE0
#define WHITE   0xFFFF
int GREY =  tft.color565(64, 64, 64);
#define GOLD 0xFEA0
#define BROWN 0xA145
#define SILVER 0xC618
#define LIME 0x07E0

int currentpcolour;

//Minimum and maximum pressure to sense the touch
#define MINPRESSURE 10
#define MAXPRESSURE 1000

#define DRAW_LOOP_INTERVAL 50  //The interval used instead of delay();

//Define the address used in the eeprom memory to store highscores
#define addr 0
int currentpage;

int currentWing;        //Used to flap the wings
int flX, flY, fallRate; //Used to calculete and store the bird's position
int pillarPos, gapPosition;  //Used tho draw the pillars
int score;              //Store the score
int highScore = 0;      //Store the highscore
bool running = false;   //Store weather flying or not
bool crashed = false;   //Store weather crashed or not
bool scrPress = false;  //Store weather sensed some touch and store
long nextDrawLoopRunTime;
int redval;
int greenval;
int blueval;

int redpos = BAR_MINY + 12;
int greenpos = BAR_MINY + 12;
int bluepos = BAR_MINY + 12;

int oldrpos = redpos;
int oldgpos = greenpos;
int oldbpos = bluepos;
int x, y;

int lastDay = 0;
int lastMonth = 0;
int lastYear = 0;
int lastHour = 0;
int lastMinute = 0;
int lastSecond=0;
int movementTimer = 0;
int menuOptions = 4;
int menuOption = 0;
int alarmHours = 0;
//int Heater_alarmMinutes = 0;
//int Heater_alarmSecond=10;
//int Motor_alarmSecond=10;
//int Motor_alarmMinutes=0;

byte Heater_alarmMinutes_end ;
byte Heater_alarmSecond_end;
byte Motor_alarmSecond_end;
byte Motor_alarmMinutes_end;

bool heater_key = 0;
bool backLightOn = 1;
int fadeValue = 255;

byte address=0;
byte value;

bool state=1;

//#$############# MLX9615 ##################

 unsigned char Re_buf[11],counter=0;
 char sign=0;
float TO=0,TA=0;
void serialEvent();

//########################################
void DrawTriangle() {
 int n, i, cx = tft.width() / 2 - 1, cy = tft.height() / 2 - 1;

 tft.fillScreen(BLACK);
 n = min(cx, cy);

 for (i = 0; i < n; i += 15) {
 tft.drawTriangle(
 cx , cy - i, // peak
 cx - i, cy + i, // bottom left
 cx + i, cy + i, // bottom right
 tft.color565(0, 0, i));
 }
}
void drawHome()
{

  tft.fillScreen(BLACK);
  tft.drawRoundRect(0, 0, 319, 240, 8, WHITE);     //Page border

  tft.fillRoundRect(60, 180, 200, 40, 8, RED);
  tft.drawRoundRect(60, 180, 200, 40, 8, WHITE);  //Game

  tft.fillRoundRect(60, 130, 200, 40, 8, RED);   //RGB led
  tft.drawRoundRect(60, 130, 200, 40, 8, WHITE);

  tft.fillRoundRect(60, 80, 200, 40, 8, RED);
  tft.drawRoundRect(60, 80, 200, 40, 8, WHITE); //Oscilloscope

  tft.setCursor(60, 20);
  tft.setTextSize(2);
  tft.setFont();
  tft.setTextColor(WHITE);
  tft.print("Select on Option");
  tft.setCursor(70, 50);
  tft.setTextSize(2);
  tft.setTextColor(LIME);
  tft.print("GSH.ir");
  tft.setTextColor(BLACK);

  tft.setCursor(80, 95);
  tft.print("Heater Setting");

  tft.setCursor(80, 145);
  tft.print("Motor  Setting");

  tft.setCursor(70, 195);
  tft.print("     Start");

  //tft.drawCircle(30, 30, 20, RED);
  //tft.fillCircle(111, 111, 30, WHITE);
  //  delay(500);
  //tft.drawRoundRect(120, 192, 60, 64, 15, YELLOW);
  // tft.fillRoundRect(0, 192, 60, 64, 15, CYAN);

   // tft.drawRect(0, 0, 60, 64, CYAN);

   //  tft.fillRect(180, 192, 60, 64, GREY);
     //DrawTriangle();

}

void drawstart(bool k)
{

  tft.fillScreen(BLACK);
  tft.drawRoundRect(0, 0, 319, 240, 8, WHITE);     //Page border

//  tft.fillRoundRect(60, 180, 200, 40, 8, RED);
//  tft.drawRoundRect(60, 180, 200, 40, 8, WHITE);  //Game
//
//  tft.fillRoundRect(60, 130, 200, 40, 8, RED);   //RGB led
//  tft.drawRoundRect(60, 130, 200, 40, 8, WHITE);
//
  tft.fillRoundRect(90, 60, 160, 60, 18, RED);
  tft.drawRoundRect(90, 60, 160, 60, 18, WHITE); //Oscilloscope

  tft.setCursor(40, 180);
  tft.setTextSize(3);
  tft.setFont();
  tft.setTextColor(WHITE);

  if (k) {
    tft.print("Motor on time");
  }else{
    tft.print("Heater on time");
  }

}
void drawMenu(bool k)
{
   tft.fillScreen(BLACK);

  tft.drawRoundRect(0, 0, 319, 240, 8, WHITE);     //Page border

//  tft.fillRoundRect(60, 180, 200, 40, 8, RED);
//  tft.drawRoundRect(60, 180, 200, 40, 8, WHITE);  //Game
//
//  tft.fillRoundRect(60, 130, 200, 40, 8, RED);   //RGB led
//  tft.drawRoundRect(60, 130, 200, 40, 8, WHITE);
//
//  tft.fillRoundRect(75, 80, 160, 60, 18, BLUE);
 // tft.drawRoundRect(700, 60, 160, 80, 18, WHITE); //Oscilloscope

  //tft.fillTriangle(60,60,20,120,180,180,RED);
  tft.fillRoundRect(70, 75, 180, 70, 18, GREEN);
   //tft.fillTriangle(42, 20, 42, 60, 90, 40, RED);
   tft.fillTriangle(260,90, 260, 130, 300, 110, RED);
   tft.fillTriangle(60,90, 60, 130, 20, 110, RED);

  tft.setCursor(45, 180);
  tft.setTextSize(2.95);
  tft.setFont();
  tft.setTextColor(WHITE);
  if (k) {
    tft.print("Motor Timer Setting");
  }else{
    tft.print("Heater Timer Setting");
  }
//  tft.fillRoundRect(5, 5, 80, 60, 8, WHITE);
//  delay(70);

  tft.setTextSize(4);
  tft.fillRoundRect(5, 5, 80, 60, 8, RED);
  tft.drawRoundRect(5, 5, 80, 60, 8, WHITE);
  tft.setCursor(20,20);
  tft.print("<-");

   tft.fillRoundRect(230, 5, 85, 60, 8, BLUE);
  tft.drawRoundRect(230, 5, 85, 60, 8, WHITE);
  tft.setCursor(250, 20);
  tft.print("OK");

}

void start(){
  tft.fillScreen(BLACK);
   drawstart(0);
   setTime(0, 0, 1, 20, 1, 2013); // hour, min, sec, day, month, year
  lastHour = hour();

          //check for heater key pressed

   heater_key=1;state =1;
 while (state ){

   if ( lastSecond!=second())
   {
       lastMinute = minute();
       lastSecond=second();
       tft.setTextSize(6);
       tft.fillRoundRect(60, 60, 200, 100, 18, RED);
       //tft.fillScreen(BLACK);
       tft.setTextColor(WHITE);
       tft.setCursor(110, 85);
       tft.print(lastMinute);
       tft.setCursor(140,85);
       tft.print(":");
       tft.setCursor(170, 85);
       tft.print(lastSecond);
       //delay(1000);
   }
   if (heater_key)
    {
      // alarm set
      if ((Heater_alarmSecond_end <= lastSecond) && (Heater_alarmMinutes_end == lastMinute))
      {
         state=0;
         digitalWrite(A5, LOW);

      }
       if ((Heater_alarmSecond_end >= lastSecond) || (Heater_alarmMinutes_end >= lastMinute))
         {
          //sound alarm
          digitalWrite(A5, HIGH);
          //setOffAlarm();
         }
     }
   }

    drawstart(1);
    state =1;
   setTime(0, 0, 0, 20, 1, 2013); // hour, min, sec, day, month, year
   while (state){
   if ( lastSecond!=second())
   {
       lastMinute = minute();
       lastSecond=second();
       tft.setTextSize(6);
       tft.fillRoundRect(60, 60, 200, 100, 18, RED);
       //tft.fillScreen(BLACK);
       tft.setTextColor(WHITE);
       tft.setCursor(110, 85);
       tft.print(lastMinute);
       tft.setCursor(140,85);
       tft.print(":");
       tft.setCursor(170, 85);
       tft.print(lastSecond);
       //delay(1000);
   }
   if (1)
    {
      // alarm set
      if ((Motor_alarmSecond_end <= lastSecond) && (Motor_alarmMinutes_end == lastMinute))
      {
         state=0;
         digitalWrite(A6, LOW);

      }
       if ((Motor_alarmSecond_end >= lastSecond) || (Motor_alarmMinutes_end >= lastMinute))
         {
          //sound alarm
          digitalWrite(A6, HIGH);
          //setOffAlarm();
         }
     }
   }

//########### MLX90615 @#############
   char i=0,sum=0;

//  for (i=0;i<100;i++){
   score=1;
    while(score==1){
    serialEvent();
    if(sign)
    {
       sign=0;
       for(i=0;i<8;i++)
        sum+=Re_buf[i];
       if(sum==Re_buf[i] )
       {
             TO=(float)(Re_buf[4]<<8|Re_buf[5])/100;
             if ((int)TO>=30){
              score=0;
             }
             tft.setTextSize(3);
             Serial.print("TO:");
             Serial.println(TO);
            tft.fillScreen(BLACK);
            tft.setCursor(10, 15);
            tft.print("Temprature :");
            tft.setCursor(10, 50);
            tft.print(TO);tft.setCursor(100, 30);tft.print("C");
             TA=(float)(Re_buf[6]<<8|Re_buf[7])/100;
             Serial.print("TA:");
             Serial.println(TA);
             delay(100);
     }
    }
  }
//####################
   delay(1000);
   drawHome();
   return;

}

void menu(){

// drawMenu();

 TSPoint p = ts.getPoint();     // Read touchscreen
 state =1;
// while(state){
// if (p.z > MINPRESSURE && p.z < MAXPRESSURE)
if (p.z > 10 && p.z < 1000)
    {
     tft.setTextSize(3);
            tft.setTextColor(RED);
            tft.setCursor(10, 10);
            tft.print(p.x);
            delay(500);

  }
// }
}
//########## MLX90615    #############
void serialEvent(){
  while (Serial1.available()) {
    Re_buf[counter]=(unsigned char)Serial1.read();
    if(counter==0&&Re_buf[0]!=0x5A) return;
    counter++;
    if(counter==9)
    {
       counter=0;
       sign=1;
    }
  }
}
//########################

void setup()
{

  time_t t = now(); // store the current time in time variable t
  pinMode(A5, OUTPUT);pinMode(A6, OUTPUT);

  tft.reset();
  tft.begin(tft.readID());
//  Serial.begin(9600);
//  Serial.println();
//  Serial.print("reading id...");
//  delay(500);
//  Serial.println(tft.readID(), HEX);

  tft.fillScreen(BLACK);
  tft.setRotation(1);

  currentpage = 0;

  tft.setTextSize(3);
  tft.setTextColor(WHITE);
  tft.setCursor(50, 140);
  tft.print("Loading...");

  tft.setTextColor(tft.color565(255, 255, 0));
  tft.setCursor(30, 70);
  tft.print("By:");

  tft.setCursor(30, 100);
  tft.print("NotesPoint.com GSH.IR");

  for (int i; i < 250; i++)
  {
    tft.fillRect(BAR_MINY - 10, BLUEBAR_MINX, i, 10, RED);
    delay(0.000000000000000000000000000000000000000000000000001);
  }

  tft.fillScreen(BLACK);
  score=14;
  if (EEPROM.read(1)==score){
  address=2;
  tft.setCursor(300, 100);
  tft.print("eeprom writed beffor");
  Heater_alarmSecond_end = EEPROM.read(address);
  Heater_alarmMinutes_end= EEPROM.read(address+1);
  Motor_alarmSecond_end = EEPROM.read(address+2);
  Motor_alarmMinutes_end = EEPROM.read(address+3);
  }
  else{
    tft.setCursor(300, 100);
  tft.print("new eeprom");
    address=1;
  EEPROM.write(address,14);
  EEPROM.write(address+1,10);
  EEPROM.write(address+2,4);
  EEPROM.write(address+3,10);
  EEPROM.write(address+4,0);
  address=1;

  Heater_alarmSecond_end = EEPROM.read(address);
  Heater_alarmMinutes_end= EEPROM.read(address+1);
  Motor_alarmSecond_end = EEPROM.read(address+2);
  Motor_alarmMinutes_end = EEPROM.read(address+3);
  }
  delay(1000);
  drawHome();
  setTime(0, 0, 0, 20, 1, 2013); // hour, min, sec, day, month, year
  //########### MLX90615 ############

Serial1.begin(115200);Serial.begin(115200);
  delay(1);
  Serial1.write(0XA5);
  Serial1.write(0X45);
  Serial1.write(0XEA);
  Serial.write(0XA5);

//#############################

}
void loop()
{

//  digitalWrite(13, HIGH);
  TSPoint p = ts.getPoint();     // Read touchscreen
//  digitalWrite(13, LOW);

  pinMode(XM, OUTPUT);
  pinMode(YP, OUTPUT);
//########### MLX90615 @#############
   char i=0,sum=0;

//  for (i=0;i<100;i++){
   score=1;
    while(score==1){
    serialEvent();
    if(sign)
    {
       sign=0;
       for(i=0;i<8;i++)
        sum+=Re_buf[i];
       if(sum==Re_buf[i] )
       {
             TO=(float)(Re_buf[4]<<8|Re_buf[5])/100;
             if ((int)TO>=30){
              score=0;
             }
             tft.setTextSize(3);
             Serial.print("TO:");
             Serial.println(TO);
            tft.fillScreen(BLACK);
            tft.setCursor(10, 15);
            tft.print("Temprature :");
            tft.setCursor(10, 50);
            tft.print(TO);tft.setCursor(100, 30);tft.print("C");
             TA=(float)(Re_buf[6]<<8|Re_buf[7])/100;
             Serial.print("TA:");
             Serial.println(TA);
             delay(100);
     }
    }
  }
//####################
  if (currentpage == 0)
  {
    if (p.z > 10 && p.z < 1000)
    {

      if (p.x > 736 && p.x < 855 && p.y > 255 && p.y < 725  && p.z > MINPRESSURE && p.z < MAXPRESSURE)
      {

        start();

//        delay(1000);

      }

      else if (p.x > 563 && p.x < 683 && p.y > 275 && p.y < 750)
      {

        currentpage = 4;
        x = 0;
        y = 0;
        p.z = 0;
/
      drawMenu(1);
      tft.setTextSize(6);
       tft.fillRoundRect(70, 75, 180, 70, 18, GREEN);
            tft.setTextColor(WHITE);
       if (Motor_alarmMinutes_end==10){
       tft.setCursor(85, 90);
       tft.print(Motor_alarmMinutes_end);
       tft.setCursor(145,90);
       tft.print(":");
       tft.setCursor(170, 90);
       tft.print(Motor_alarmSecond_end);
       }else{
       tft.setTextColor(WHITE);
       tft.setCursor(110, 90);
       tft.print(Motor_alarmMinutes_end);
       tft.setCursor(140,90);
       tft.print(":");
       tft.setCursor(170, 90);
       tft.print(Motor_alarmSecond_end);

       }

      }

      if (p.x > 403 && p.x < 525 && p.y > 271 && p.y < 725)
      {
//        Serial.println("Oscilloscope");

        currentpage =5;

//        tft.fillRoundRect(60, 80, 200, 40, 8, WHITE);
//        delay(70);
//
//        tft.fillRoundRect(60, 80, 200, 40, 8, RED);
//        tft.drawRoundRect(60, 80, 200, 40, 8, WHITE);
//
//        tft.setCursor(80, 95);
//        tft.print("Oscilloscope");
//        delay(70);
        drawMenu(0);
        tft.setTextSize(6);
       tft.fillRoundRect(70, 75, 180, 70, 18, GREEN);
            tft.setTextColor(WHITE);
       if (Heater_alarmMinutes_end==10){
       tft.setCursor(85, 90);
       tft.print(Heater_alarmMinutes_end);
       tft.setCursor(145,90);
       tft.print(":");
       tft.setCursor(170, 90);
       tft.print(Heater_alarmSecond_end);
       }else{
       tft.setTextColor(WHITE);
       tft.setCursor(110, 90);
       tft.print(Heater_alarmMinutes_end);
       tft.setCursor(140,90);
       tft.print(":");
       tft.setCursor(170, 90);
       tft.print(Heater_alarmSecond_end);

       }
//        drawOSC();

      }
    }

  }

  if (currentpage == 4){
//   menu();

       //tft.fillScreen(BLACK);

if (p.z > 10 && p.z < 1000)
    {
//     tft.setTextSize(3);
//            tft.setTextColor(RED);
//            tft.setCursor(10, 10);
//            tft.print(p.x);
//            //delay(500);

       tft.setTextSize(6);
       tft.fillRoundRect(70, 75, 180, 70, 18, GREEN);
            tft.setTextColor(WHITE);
       if (Motor_alarmMinutes_end>=10){
       tft.setCursor(85, 90);
       tft.print(Motor_alarmMinutes_end);
       tft.setCursor(145,90);
       tft.print(":");
       tft.setCursor(170, 90);
       tft.print(Motor_alarmSecond_end);
       }else{
       tft.setTextColor(WHITE);
       tft.setCursor(110, 90);
       tft.print(Motor_alarmMinutes_end);
       tft.setCursor(140,90);
       tft.print(":");
       tft.setCursor(170, 90);
       tft.print(Motor_alarmSecond_end);

       }

      if (p.y > 600 && p.x < 650 && p.x > 400 && p.y < 885)
        {
         if (Motor_alarmSecond_end==0){
                Motor_alarmSecond_end=59;
                if (Motor_alarmMinutes_end==0){
                    Motor_alarmMinutes_end=10;}
                else {
                      Motor_alarmMinutes_end=Motor_alarmMinutes_end-1;
                }
                }
          else {
            Motor_alarmSecond_end=Motor_alarmSecond_end-1;
            }
           }

          if (p.y > 150 && p.x < 700 && p.x > 400 && p.y < 400)
        {
         if (Motor_alarmSecond_end==59){
                Motor_alarmSecond_end=0;
                if (Motor_alarmMinutes_end==10){
                    Motor_alarmMinutes_end=0;
                     }
                else {
                      Motor_alarmMinutes_end=Motor_alarmMinutes_end+1;
                     }
                }
          else {
            Motor_alarmSecond_end=Motor_alarmSecond_end+1;
            }
           }
       if (p.y > 200 && p.x < 375 && p.x > 200 && p.y < 350)
      {

          EEPROM.write(address+3,Motor_alarmSecond_end);
          EEPROM.write(address+4,Motor_alarmMinutes_end);

        currentpage = 0;
        drawHome();
//        p.x = 160;
//        p.y = 760;
        return;
      }
       if (p.y > 750 && p.x < 315 && p.x > 50 && p.y < 1000)
      {

        currentpage = 0;
        drawHome();

        return;
      }

  }
}

if (currentpage == 5){
//   menu();

       //tft.fillScreen(BLACK);

if (p.z > 10 && p.z < 1000)
    {
//     tft.setTextSize(3);
//            tft.setTextColor(RED);
//            tft.setCursor(10, 10);
//            tft.print(p.x);
//            //delay(500);

       tft.setTextSize(6);
       tft.fillRoundRect(70, 75, 180, 70, 18, GREEN);
            tft.setTextColor(WHITE);
       if (Heater_alarmMinutes_end>=10){
       tft.setCursor(85, 90);
       tft.print(Heater_alarmMinutes_end);
       tft.setCursor(145,90);
       tft.print(":");
       tft.setCursor(170, 90);
       tft.print(Heater_alarmSecond_end);
       }else{
       tft.setTextColor(WHITE);
       tft.setCursor(110, 90);
       tft.print(Heater_alarmMinutes_end);
       tft.setCursor(140,90);
       tft.print(":");
       tft.setCursor(170, 90);
       tft.print(Heater_alarmSecond_end);

       }

        if (p.y > 600 && p.x < 650 && p.x > 400 && p.y < 885)
        {
         if (Heater_alarmSecond_end==0){
                Heater_alarmSecond_end=59;
                if (Heater_alarmMinutes_end==0){
                    Heater_alarmMinutes_end=10;}
                else {
                      Heater_alarmMinutes_end=Heater_alarmMinutes_end-1;
                }
                }
          else {
            Heater_alarmSecond_end=Heater_alarmSecond_end-1;
            }
           }

          if (p.y > 150 && p.x < 700 && p.x > 400 && p.y < 400)
        {
         if (Heater_alarmSecond_end==59){
                Heater_alarmSecond_end=0;
                if (Heater_alarmMinutes_end==10){
                    Heater_alarmMinutes_end=0;
                }
                else {
                      Heater_alarmMinutes_end=Heater_alarmMinutes_end+1;
                }
                }
          else {
            Heater_alarmSecond_end=Heater_alarmSecond_end+1;
            }
           }
        if (p.y > 200 && p.x < 375 && p.x > 200 && p.y < 350)
      {

          address=1;
          EEPROM.write(address+1,Heater_alarmSecond_end);
          EEPROM.write(address+2,Heater_alarmMinutes_end);

        currentpage = 0;
        drawHome();
//        p.x = 160;
//        p.y = 760;
        return;
      }
      if (p.y > 750 && p.x < 315 && p.x > 50 && p.y < 1000)
      {

        currentpage = 0;
        drawHome();
//        p.x = 160;
//        p.y = 760;
        return;
      }

  }
}
  if (currentpage == 1) //Flappy bird
  {
    senseBack();
    if (millis() > nextDrawLoopRunTime && !crashed) {
      drawLoop();
      checkCollision();
      nextDrawLoopRunTime += DRAW_LOOP_INTERVAL;
    }
    if (backsensed)
    {
      currentpage = 0;
      drawHome();
    }

    sensereset();

    ResetScore();

    // Process user input   If sensed a touch anywere on the screen eccept the area of the reset button
    if (p.z > MINPRESSURE && p.z < MAXPRESSURE && !scrPress && !resetsensed && !backsensed) {     //p.x < 199 && p.y < 293
      if (crashed) {
        // restart game
        startGame();
      }
      else if (!running) {
        // clear and restart
        tft.fillRect(0, 0, 320, 80, BLUE);
        running = true;
      }
      else
      {
        // Go up
        fallRate = -8;
        scrPress = true;
      }
    }
    else if (p.z == 0 && scrPress) {
      scrPress = false;
    }
  }

  if (currentpage == 2) // RGB mixer
  {

    if (p.z > MINPRESSURE && p.z < MAXPRESSURE)
    {
      x = map(p.x, TS_MINX, TS_MAXX, tft.width(), 0);
      y = map(p.y, TS_MINY, TS_MAXY,  tft.height(), 0) + 30;

      tft.fillRoundRect(200, 5, 70, 40, 8, tft.color565(redval, greenval, blueval));

      if (y > 42 && y < 250)
      {
        if (x > 180 && x < 220)
        {

          redval = map(y, 42, 250, 0, 255);
          oldrpos = redpos;
          tft.fillRect(oldrpos, REDBAR_MINX + 3, BAR_WIDTH - 10, BAR_WIDTH - 5, BLACK);
          redpos = y;
          tft.fillRect(redpos, REDBAR_MINX + 3, BAR_WIDTH - 10, BAR_WIDTH - 5, RED);      //tft.drawRect(BAR_MINY, REDBAR_MINX, BAR_HEIGHT, BAR_WIDTH, WHITE);
          tft.fillCircle(14, REDBAR_MINX + 15, 10, tft.color565(redval, 0, 0));

        }

        if (x > 115 && x < 150)
        {
          greenval = map(y, 42, 250, 0, 255);
          oldgpos = greenpos;
          tft.fillRect(oldgpos, GREENBAR_MINX + 3, BAR_WIDTH - 10, BAR_WIDTH - 5, BLACK);
          greenpos = y;
          tft.fillRect(greenpos, GREENBAR_MINX + 3, BAR_WIDTH - 10, BAR_WIDTH - 5, GREEN);      //tft.drawRect(BAR_MINY, REDBAR_MINX, BAR_HEIGHT, BAR_WIDTH, WHITE);
          tft.fillCircle(14, GREENBAR_MINX + 15, 10, tft.color565(0, greenval, 0));

        }
        if (x > 40 && x < 80)
        {
          blueval = map(y, 42, 250, 0, 255);
          oldbpos = bluepos;
          tft.fillRect(oldbpos, BLUEBAR_MINX + 3, BAR_WIDTH - 10, BAR_WIDTH - 5, BLACK);
          bluepos = y;
          tft.fillRect(bluepos, BLUEBAR_MINX + 3, BAR_WIDTH - 10, BAR_WIDTH - 5, BLUE);      //tft.drawRect(BAR_MINY, REDBAR_MINX, BAR_HEIGHT, BAR_WIDTH, WHITE);
          tft.fillCircle(14, BLUEBAR_MINX + 15, 10, tft.color565(0, 0, blueval));

        }
      }

      if (p.y > 743 && p.x < 247 && p.x > 150 && p.y < 875)
      {
        tft.fillRoundRect(5, 5, 50, 30, 8, WHITE);
        delay(70);
        tft.fillRoundRect(5, 5, 50, 30, 8, BLUE);
        tft.drawRoundRect(5, 5, 50, 30, 8, WHITE);
        tft.setCursor(15, 15);
        tft.print("<-");
        delay(70);
        tft.fillRoundRect(5, 5, 50, 30, 8, BLACK);
        currentpage = 0;
        drawHome();
        p.x = 160;
        p.y = 760;
        redval = 0;
        blueval = 0;
        greenval = 0;
        redpos = BAR_MINY + 12;
        greenpos = BAR_MINY + 12;
        bluepos = BAR_MINY + 12;
        oldrpos = redpos;
        oldgpos = greenpos;
        oldbpos = bluepos;

      }
    }

  }

  if (currentpage == 3)  //Oscilloscope
  {
    for (uint16_t j = 0; j <= tft.width() + 1; j++ )

    {
      float volt;
      float signalY = map(analogRead(A5),  0,  4095,  tft.height() - 1,  1   ) ;

      tft.drawFastVLine( j,  46, tft.height(), BLACK);
      tft.drawFastHLine(j, 180.00, 1, RED);
      tft.drawFastHLine(j, 195.00, 1, WHITE);

      tft.drawPixel(j, signalY, GOLD);

      if (p.z > MINPRESSURE && p.z < MAXPRESSURE)
        if (p.y > 743 && p.x < 247 && p.x > 150 && p.y < 875)
        {
          tft.fillRoundRect(5, 5, 50, 30, 8, WHITE);
          delay(70);
          tft.fillRoundRect(5, 5, 50, 30, 8, BLUE);
          tft.drawRoundRect(5, 5, 50, 30, 8, WHITE);
          tft.setCursor(15, 15);
          tft.print("<-");
          delay(70);
          tft.fillRoundRect(5, 5, 50, 30, 8, BLACK);
          currentpage = 0;
          drawHome();
          p.x = 160;
          p.y = 760;
          return;
        }

    }
  }

}

void drawLoop() { //Flappy bird functions
  // clear moving items
  clearPillar(pillarPos, gapPosition);   //Clear pillar
  clearFlappy(flX, flY);            //Clear bird

  // Move items
  if (running) {
    flY += fallRate;
    fallRate++;

    pillarPos -= 5;
    if (pillarPos == 0) {
      score++;
    }
    else if (pillarPos < -50) {
      pillarPos = 320;
      gapPosition = random(20, 120);    //Random gap position
    }
  }

So now i removed this part from my program but how could I add this font to my library?
Update:
My arduino Version is 1.8.9 similar this:

Thanks

How did you install the Linux version of Arduino? Did you download from arduino.cc? If not you are probably using a very very very old version that does not include the library include mechanism.

really i don't remember how to installed it but  in arduino website the version 1.8.9 which is mine is the last version.


text:
Buzzer interfere with thermistor reading
This is how i wired the thermistor and buzzer:

simulate this circuit – Schematic created using CircuitLab
And the code:
#define RT0 10000
#define B 3977
#define R 10000
float RT, VR, ln, TX, T0, VRT;

void setup() {
  T0 = 25 + 273.15;
}

void loop() {
  VRT = analogRead(A3);
  VRT = (5.00 / 1023.00) * VRT;
  VR = 3.3 - VRT;
  RT = VRT / (VR / R);
  ln = log(RT / RT0);
  TX = (1 / ((ln / B) + (1 / T0)));
  TX = TX - 273.15;
}

When i connect the buzzer it causes a bit of voltage drop which messes with temperature reading, How can i get a steady temperature reading while having a buzzer in the circuit?

Use the output of the LF33CV as your AREF?

How much is the voltage dropping? Can you simply use a power source, that can handle the buzzers current, without dropping the voltage? And in your schematics the buzzer is connected permanently, so the voltage drop should be consistent, which means, that you would be able to work around it by measuring the resulting voltage and include that in your calculations

@Majenko how? connect the 3.3V to the AREF pin AND thermistor?

@chrisl i didn't measure the voltage drop but it should be ~1V, it's an active buzzer. buzzer is controlled with MCU, i just didn't add that to the schematic...

@newbie Yep. and set analogReference(EXTERNAL); -- https://www.arduino.cc/reference/en/language/functions/analog-io/analogreference/

You can use the output of your regulator as the reference voltage for your analog readings. That way, no matter what the voltage you voltage divider for the thermistor uses, the "upper" voltage that the ADC uses is always the same as the thermistor's voltage.
Simply connect the output of the regulator to the AREF pin, and set the ADC to use the external voltage reference:
analogReference(EXTERNAL);

Now you have the range 0-1023 covering 0-3.3V (or whatever the voltage is the regulator is outputting), and because the output of your voltage divider is just a ratio of that voltage, that ratio will always be a ratio of 1023, regardless of what the voltage happens to be.
You have, in effect, removed the voltage from the equation. All you are left with is the value as a fraction of 1023, which is then directly proportional to the resistance of the thermistor.

I did just what said and the reading is steady even with voltage drop, a side question; in this line VR = 3.3 - VRT; voltage is defined 3.3V but i'm getting false reading with that and have to change it to VR = 5 - VRT;. isn't AREF voltage and the voltage on the thermistor/resistor voltage divider 3.3V? why i have to define it 5V to get proper temperature reading?

Because in the line before you have 5v for the voltage. Change that to 3.3v.

After a bit of research i realized that LF33Cv is not a reliable Vref, do you suggest LM336 or TL431?

Stability doesn't matter for this application. Nor does the voltage. You could use any voltage that is within spec of the ADC and the results will be the same. You only care about an accurate Vref if you are comparing something external to that Vref. You're not.  You're just looking at a ratio of two resistors between Vref and GND.  The formula for R2 can be reduced to just (A * 10000) / (1023 - A) where A is the value read from the ADC. There's no voltage in there at all. It all cancels out.

Thanks and sorry for question after question... i have a hall effect sensor UGN35 which is also connected to to analog pin and the analog reading is changing with voltage drop, in this specific case should i change the Vref source to TL431 or is it something that can be fixed with software?

@newbie Maybe you should be addressing why you are getting a voltage drop instead of trying to compensate for it.

even turning on a simple LED causes changes in analog reading of the hall effect sensor! it's not much but it is something... should i ask this in a separate question?

Yeah. And provide a full detailed schematic.

Take the regulator output to another analog input. Read that just before you read the thermistor. Use that voltage in your voltage divider calculation. The buzzer activity should be the same (ideally, off) during both readings.


text:
Not Able to get INPUT_PULLUP pinmodes to work on multiple pins
I am working with an Arduino nano, and ic2 128x32 OLED display and a 1x4 membrane keypad. Problem is that only one of the 4 pins are detecting the button press. it's not the Arduino, I already was able to reproduce the same issue on another one. the keypad is also working fine, as I have tested it. (edit now only pin 9 is working)
#define b1 6
#define b2 7
#define b3 8
#define b4 9

// in setup

pinMode(b1, INPUT_PULLUP);
pinMode(b2, INPUT_PULLUP);
pinMode(b3, INPUT_PULLUP);
pinMode(b4, INPUT_PULLUP);

// in loop

int b1S = digitalRead(b1);
  int b2S = digitalRead(b2);
  int b3S = digitalRead(b3);
  int b4S = digitalRead(b4);

  if(!b1S){
    Serial.println("Button 1");
    }

  if(!b2S){
    Serial.println("Button 2");
    }

  if(!b3S){
    Serial.println("Button 3");
    }

  if(!b4S){
    Serial.println("Button 4");
    }

Please help! Thanks

How is everything connected? Have you measured, if there is 5V on the specified pins, when you don't press a button? Also measure without the keypad

to answer how its connected, each pin defined in the code is connected to one of the inputs of the buttons on the keypad with it all connected to a common ground

and b2 and b4 are giving around 4v and the other 2 are giving readings somewhere in the millivolts, that's not right, right?

I'd suggest backing up and testing each part separately. Get a breadboard and a momentary switch. Connect the switch through to ground on one pin at a time. See if a test sketch is able to detect the change in state for each pin when it's configured as INPUT_PULLUP. If not, try using INPUT, and attaching the pin to +5V through a 10kΩ resistor.  Also use an ohm-meter to verify that your membrane switches are open unless pressed, and connect to ground when they are pressed.

Have you measured these voltages with connected keypad? If yes, try without the keypad - just the bare arduino. If the voltages are still that low, the Arduino is probably broken.


text:
My GY-MAX30100 pulse oximeter issue with Arduino Uno
I connected the purple oximeter (GY-MAX30100) to the Arduino Uno with the following connections.
OXIMETER       ARDUINO UNO
VIN              5V
GND              GND
SCL              SCL
SDA              SDA
INT              D2

It shows me inaccurate measurements.
13:16:02.851 -> Pulse oxymeter test!
13:16:02.851 -> BEAT
13:16:02.851 -> BPM: 8616.35 | SaO2: 92.01%
13:16:03.055 -> BEAT
13:16:03.055 -> BPM: 4313.73 | SaO2: 92.66%
13:16:03.089 -> BEAT
13:16:03.089 -> BPM: 1209.15 | SaO2: 92.74%

I used this sketch from github
https://github.com/xcoder123/MAX30100/blob/master/max30100.ino
This is the sensor
EDIT
I have run an I2C scanner and this is the result: I2C device found on address 0x57. The library has the same address hard coded in it.

You might want to include a link to the library that sketch uses. Given how specific your question is, you might not get much help here. (Your potential pool of help is going to be people who have used the same sensor, with the same library, using the same sketch.) I'd suggest contacting the author of the sketch.

BTW, how does that sensor work? Every pulse-ox sensor I've ever seen shines a red light through a finger or other body part, and puts a sensor on the other side. That sensor doesn't appear to have separate emitter and sensor parts.

@DuncanC - This sensor has a visible light LED, IR LED and a Photodiode all built in :)

Ok, but it doesn't have a gap into which you would put your finger. Does it shine light into your body and then measure the light reflected back?

@DuncanC - All you have to do is put your finger on the sensor. https://datasheets.maximintegrated.com/en/ds/MAX30100.pdf


text:
Arduino Mega's auxiliary serial ports
If I am correct, the first two pins (RX/TX) are connected to the USB, and I cannot use the serial monitor and the first RX/TX serial ports at the same time.
But, what about the other 3 auxiliary serial ports? Are they separated? Do each one of them has it's own buffer?
For example: Is it possible to add, let's say, four Bluetooth modules(Let's say HC-05) and use each of them for a different purpose?

Just to complement JRobert's answer: yes, the four serial ports are
independent. They can be activated independently, they can be set to
different baud rates if needed, and they do have separate buffers.

You can indeed use a serial monitor on your PC on the Mega's first serial port, in fact you will have to if you are connecting to one on the PC via USB port.. And just as with the Uno, you can connect a TTL serial device (like RS-232 serial, but using logic levels of 0 and +5v instead of [-3v - -25v] and [+3v - +25v] (which most PCs implemented as -12v and +12v).
If you need to connect to a true RS-232 device, you'll need to convert the TTL logic levels to something within the RS-232 spec; -5v and +5v would probably be the easiest.

Serial1, Serial2 and Serial3 are all independent, at 0/5V levels.
You can each one to a bluetooth module, or whatever HC-05 is.
Or FTDI Basic modules if you want more USB ports.
Etc.


text:
How to actually concatenate two Strings?
I'm using the SPISlave library, and I have the following code snippet:

String arg;

SPISlave.onData([arg](uint8_t *data, size_t len) {
  data[len] = 0;
  arg += String((char *)data);
  // ...
}

The compiler doesn't like my string concatenation, though:

/home/lars/sketch_apr01a/sketch_apr01a.ino: In lambda function:
  sketch_apr01a:65:12: error: passing 'const String' as 'this' argument
  of 'String& String::operator+=(const String&)' discards qualifiers
  [-fpermissive]
         arg += String((char *)data);

I've tried other versions as well, with similar results:

arg.concat((char *)data)
arg = arg + String((char *)data)
arg += String((const char *)data)

So how exactly do I write this unusual operation?

Funny, on avr-g++ it's fine (with warnings about store duration). Anyway, you are capturing the arg variable by value, so it won't affect variable outside lambda function.

Your lambda is capturing arg by copy, which is most certainly not what
you want. And since it doesn't have the mutable qualifier, the
captured parameters are not modifiable. Hence the compiler error.
You could get rid of the error by qualifying the capture as mutable,
but you would then be modifying the captured copy of arg, not the
original one. The correct solution would be to capture the String by
reference instead of capturing by copy. See Lambda
expressions.
But then, I concur with Michel Keijzers that avoiding Strings altogether
is a better option.

Makes perfect sense, thanks!

Thanks for the insight and correct answer too (upvoted)

Actually for such string concatenation (which is in a function that may be called a lot), this could result in memory fragmentation, an on most Arduinos the memory will be soon too scattered that no useful memory is left.
Instead, it's better to create beforehand a buffer with the maximum size of the string you want to handle, like:
static const int MAX_BUFFER_LENGTH = 256;

char buffer[MAX_BUFFER_LENGTH];

And use the function strcat or strncat for concatenating two strings; there are generic C functions.

Fair enough, and good advice in general.  But I'd still like to know the answer to my question. :-)

I wonder what error you get when using concat (cannot be a String passing operation error). Maybe some casting to const.

#include <stdio.h>

static const int MAX_BUFFER_LENGTH = 32;
char buffer[MAX_BUFFER_LENGTH];

sprintf(buffer, "%s%s", string1, string2);


text:
Arduino malfunction tmrpcm while used digitalRead
I am programming Arduino UNO for this functionality:
with use of SD card reader module and SIM900 GSM/GPRS shield I am trying to:
 1. Pick up incomming call, play message from SD file and after the message ends, hang up.
 2. Call from Arduino to defined telephone number, after the call is picked up, play message and after the message ends, hang up.
3. In case of outcomming call (arduino calls to defined number) and its declined or not picked up, Arduino makes another try for a total of 3 tries.
4. I want to play the message in Czech language OR English message, based on pushed/unpushed button.
Its all working, but number 4. the button for language switch is not working. If I place in code another "digitalRead(pin)" Arduino does all the stuff but does not play the message - its silent on the other end. If I delete this line of code, it is working. So the functionality is good, but the language switch is not working. I have tried to switch it to Global/Local variables, tried to put it straight into the If statement. Everything is wrong.
Any ideas? Thank you.
Code:

#include <GPRS_Shield_Arduino.h>
#include <SoftwareSerial.h>
#include <Wire.h>
#include <SD.h>
#include <TMRpcm.h>
#include "SPI.h"

#define SD_ChipSelectPin 10
#define PIN_TX    7
#define PIN_RX    8
#define BAUDRATE  9600
#define MESSAGE_LENGTH 20

GPRS gprs(PIN_TX, PIN_RX, BAUDRATE);
TMRpcm tmrpcm;

char telefon[] = "999999999";
//char *s = NULL;
char englishMessage[] = "Hlas6en.wav";
char czechMessage[] = "Hlas6cz.wav";//"Hlas6cz.wav";
char gprsBuffer[64];
//char in_number[16] = {0};

unsigned long englishMessageTime = 11000;
unsigned long czechMessageTime = 11000;

int callRetry = 2; //pocet pokusu opakovaneho telefonatu
//int i = 1;
//int inComing = 0;

bool callPrev = false;
bool callAct = false;
bool call = false;

uint8_t PIN_RST = 2;
int PIN_INPUT = 4;
//int LANGUAGE_INPUT = 6;
bool languageSwitch = HIGH;

void setup()
{
  pinMode(PIN_INPUT, INPUT_PULLUP);
  pinMode(3, INPUT_PULLUP);

  Serial.begin(BAUDRATE);
  //delay(10000); //NECHAT!

  while (!gprs.init())
  {
    Serial.println("SIM 900 - INIT ERROR");
    gprs.powerReset(PIN_RST);
    delay(7000);
  }

  while (!SD.begin(SD_ChipSelectPin))//SD_ChipSelectPin
  {
    Serial.println("SD fail");
    delay(1000);
    //return;
  }
  Serial.println("Zapnuto.");
  tmrpcm.speakerPin = 9;
  tmrpcm.setVolume(5);
  //sim900_clean_buffer(gprsBuffer, 32);
  //gprs.callUp(telefon);
  //languageSwitch = digitalRead(3);
}

void loop() {
  if ((gprs.readable()) || call)
  {
    sim900_read_buffer(gprsBuffer, 32, DEFAULT_TIMEOUT);
    Serial.print(gprsBuffer);
    if (NULL != strstr(gprsBuffer, "OK"))
    {
      Serial.println("Hovor prijat.");
      playAudio();
      Serial.println("Zprava prehrana, pokladam.");
      gprs.hangup();
      callRetry = 2;
    }
    else if (NULL != strstr(gprsBuffer, "RING"))
    {
      Serial.println("Prijimam prichozi hovor.");
      gprs.answer(); //zvednuti telefonu v pripade prichoziho hovoru
      callRetry = 2;
    }

    else if ((NULL != strstr(gprsBuffer, "BUSY")) || call)
    {

      if (callRetry == 0)
      {
        callRetry = 2;
        Serial.println("Nedovolal jsem se.");
      }
      else if ((callRetry > 0) && (!call))
      {
        Serial.print("Zbyva pocet pokusu:");
        Serial.println(callRetry - 1);
        gprs.callUp(telefon); //Opakovane volani v pripade polozeni
        callRetry--;
      }
      else if ((callRetry == 2) && (call))
      {
        gprs.callUp(telefon);
        Serial.println("Volam");
      }
      call = false;
    }
    //smazani bufferu
    sim900_clean_buffer(gprsBuffer, 32);
  }
  callPrev = callAct;
  callAct = !digitalRead(PIN_INPUT);
  //languageSwitch = digitalRead(3);
  call = !callPrev && callAct;
  //languageSwitch=digitalRead(LANGUAGE_INPUT);
  delay(1000);
  Serial.println(call);
  //Serial.println(languageSwitch);
}

void playAudio()
{
  bool languageSwitch = digitalRead(3); //PROBLEM!!!
  tmrpcm.speakerPin = 9;
  if (!SD.begin(SD_ChipSelectPin))//SD_ChipSelectPin
  {
    Serial.println("SD fail");
    return;
  }
  Serial.println("Prehravani zpravy.");
  tmrpcm.setVolume(5);
  if (languageSwitch==HIGH)
  {
    Serial.println("Prehravam zpravu v cestine");
    tmrpcm.play(czechMessage);//czechMessage
    delay(czechMessageTime);
  }
  else
  {
    Serial.println("Prehravam zpravu v anglictine");
    tmrpcm.play(englishMessage);//englishMessage
    delay(englishMessageTime);
  }
  return;
}

How is the button connected to the Arduino? Do you have a pullup/down resistor, can you show a schematic?

As you can see, the pin is initialized in pinmode input_pullup so if there is nothing connected it should be all time high. And it is. If I use println with the pin state it represents the correct state ,it just does not play the message from SD.

But you said you execute the tmrpcm.play(czechMessage); yourself it does play the sound, so only inside playAudio() the digitalRead doesn't work? Is it stuck to always the same value or random?

It doesn't matter where the digital read is. If it is present in the loop or inside the playAudio() function. If it is present anywhere the message - sound is not playing. If you delete the digitalRead sound is playing properly.

Otherwise the digitalRead is working properly - high on unpressed button, low on pressed button. It just mess up the play of the audio message.


text:
How to stop OLED flicker when using SSD1306Ascii.h?
Why does the OLED display flicker when using the SSD1306Ascii.h library? The Adafruit library does not have this issue, but I've been told uses a lot of memory and so I'm trying to use Ascii to conserve memory resources. The problem manifests itself when the void loop() begins. When using similar code with the Adafruit library, the display stays steady as a rock.
Here is my example code. many thanks in advance.
// Edit AVRI2C_FASTMODE in SSD1306Ascii.h to change the default I2C frequency.

#include "SSD1306Ascii.h"
#include "SSD1306AsciiAvrI2c.h"

#define I2C_ADDRESS 0x3C

// Define proper RST_PIN if required.
#define RST_PIN -1

SSD1306AsciiAvrI2c oled;
//------------------------------------------------------------------------------
void setup() {

#if RST_PIN >= 0
  oled.begin(&Adafruit128x64, I2C_ADDRESS, RST_PIN);
#else // RST_PIN >= 0
  oled.begin(&Adafruit128x64, I2C_ADDRESS);
#endif // RST_PIN >= 0
  // Call oled.setI2cClock(frequency) to change from the default frequency.

  oled.setFont(System5x7);
  oled.clear();
  oled.print("Hello World!");
  delay(2000);
  oled.clear();

}
//------------------------------------------------------------------------------
void loop() {

  oled.setFont(System5x7);
  oled.print("Hello fuuuzzzzyyyy world!");
  delay(1);
  oled.clear();

}

how do you know that the problem is caused by the library?

what debugging have you done?

I've played around with the frequency settings which speeds up or slows down the flicker, but like I say the more common Adafruit library doesn't produce this effect when running through the loop. I'm pretty new to this so any guidance is much appreciated.

Also, i think there may be ways around it using other methods in the library to only manipulate the areas where a value is changing, but it will get messy...

don't run clear(). make an array that fits the screen, fill the array as needed with data (don't forget to write spaces for blanks), and write the whole array to the screen each time.

Yes, I was thinking along those lines, thanks for the help I'll give it a try.

Your loop is repeatedly writing and clearing the display, nearly as fast as possible (minus the 1ms delay at the bottom), which is the reason for the flicker you're seeing. If instead, you only update the display when something changes, it will look much smoother. Even a clear-and-rewrite the entire display when something changes (assuming the changes are infrequent) will be a major improvement. Of course this assumes you'd eventually be writing dynamic data; your test program, of course, writes and re-writes static data.
Update:

If I run the same code structure with Adafruit library there is no
  flicker, even with no delay in the loop.

Can you compare the two libraries to see what they do differently?

The Adafruit library does not have this issue, but I've been told uses
  a lot of memory

There's a likely clue: Adafruit may be buffering the display contents in memory so it can find out which character positions changed and update only those. That would be a classic time/space trade-off.

I'm displaying values from a Gyro so needs to update continually. If you set the delay to 1 second, there is still a noticeable flicker as the display refreshes. If I run the same code structure with Adafruit library there is no flicker, even with no delay in the loop.

Yes, it's due to rewriting the whole display.  I generally only rewrite portions that have changed or at worst use the ClearToEOL command to make sure everything's obliterated.

You could only rewrite those parts of the display that change which is the gyro value


text:
typedef function pointer array declaration problem
Thanks for all your feedback. It helped.
I rewrote this yet another time and this time it works perfectly. I included three variations: a simple example using an array of function pointers, a Lambda version and a complex version like what I started with.
#define TASK_COUNT          3

typedef void ( *taskPointer ) ( );

//  Simple Version:
void taskS1 () { Serial.println ( ( char* )"SIMPLE TASK 1" ); }
void taskS2 () { Serial.println ( ( char* )"SIMPLE TASK 2" ); }
void taskS3 () { Serial.println ( ( char* )"SIMPLE TASK 3" ); }

//  Array of pointers to tasks
taskPointer callSimpleTask [ ] = {
taskS1,
taskS2,
taskS3,
};

//  Run the simple test
void showSimpleVersion () {
    Serial.println ( F ( "\nSimple Version:" ) );
    for (uint8_t i = 0; i < TASK_COUNT; i++) {
        callSimpleTask [ i ] ();
    }

}

//  Lambda Version: No separate task definitoins
void ( *callLambdaTask [ ] ) ( ) = {
    [ ] {Serial.println ( ( char* )"LAMBDA TASK 1" ); },
    [ ] {Serial.println ( ( char* )"LAMBDA TASK 2" ); },
    [ ] {Serial.println ( ( char* )"LAMBDA TASK 3" ); },
};

//  Run the Lambda test
void showLambdaVersion () {
    Serial.println ( F ( "\nLambda Version:" ) );
    for (uint8_t i = 0; i < TASK_COUNT; i++) {
        callLambdaTask [ i ] ();
    }

}

//  Complex Version: Each array element is a struct containing a
//  pointer to the corresponding task and related properties
struct complexTaskDefinition {
    taskPointer task;
    bool repeat;                //  Repeat flashing after delay
    int32_t iterations;         //  # times to repeat... -1 = forever
    uint32_t delay;             //  MS to wait before execution
};

//  Create a pointer to a task definition
complexTaskDefinition *task;

//  Prove that called function can call other functions:
void taskC1 () { showTaskC1(); }
void taskC2 () { showTaskC1 (); }
void taskC3 () { showTaskC1 (); }

void showTaskC1 () {
    Serial.println ( ( char* )"COMPLEX TASK 1" );
}
void showTaskC2 () {
    Serial.println ( ( char* )"COMPLEX TASK 2" );
}
void showTaskC3 () {
    Serial.println ( ( char* )"COMPLEX TASK 3" );
}

complexTaskDefinition tasks [ ] [4] = {
    {taskC1, true, -1, 1000 },  //  taskC1 repeats forever every second
    {taskC2, true, 10, 2000 },  //  taskC2 runs 10 times pausing for 2 seconds between iterations
    {taskC3, false, 3, 3000 },  //  taskC3 runs 3 times with 3 second delays between each, then dies
};

void showComplexTaskList () {
    Serial.println ( F ( "\nComplex Task List:" ) );
    for (uint8_t i = 0; i < TASK_COUNT; i++) {
        task = tasks [ i ];
        Serial.print ( '[' );
        Serial.print ( i );
        Serial.print ( F ( "] REPEAT:" ));
        Serial.print ( ( task->repeat ) ? "YES" : "NO" );
        Serial.print ( F ( ", DELAY:" ) );
        Serial.print ( task->delay );
        Serial.print ( F ( ", ITERATIONS:" ) );
        Serial.print ( task->iterations );
        Serial.println ();
    }
}

void showComplexVersion () {
    Serial.println ( F ( "\nComplex Version:" ) );
    for (uint8_t i = 0; i < TASK_COUNT; i++) {
        task = tasks [ i ];
        task->task ();
//      (( *tasks ) [ i ]).task ();
    }
}

void setup () {
    Serial.begin ( 115200 );
    while (!Serial.availableForWrite ()) {}

    showSimpleVersion ();

    showLambdaVersion ();

    showComplexVersion ();

    showComplexTaskList ();
}

void loop () {
}

Here is the output:
Simple Version:
SIMPLE TASK 1
SIMPLE TASK 2
SIMPLE TASK 3

Lambda Version:
LAMBDA TASK 1
LAMBDA TASK 2
LAMBDA TASK 3

Complex Version:
COMPLEX TASK 1
COMPLEX TASK 1
COMPLEX TASK 1

Complex Task List:
[0] REPEAT:YES, DELAY:1000, ITERATIONS:-1
[1] REPEAT:YES, DELAY:2000, ITERATIONS:10
[2] REPEAT:NO, DELAY:3000, ITERATIONS:3

I want to run one more experiment, this time with the complex version as a class.

loop() and setup()?

What compiler error do you get?

Board? Arduino IDE version? It can be compiled wihout any warning/error for AVR based board.  Btw: &task1, &task2, &task3 is more correct.

@KIIV As from C99 the & is entirely optional for function pointers. Neither is "more correct" than the other, they are both completely correct.

@majenko in C yes. In C++ there are also cases where it's required (like member function pointers). More correct was meant like "yes, i want function pointer, I didn't forget ()" - showing clear intention

I don't understand why did you ask the question without the error message and the part of the sketch where the error occurs and only added them later

Try replacing
taskDefinition _tasks [ ] [4] = {

by
taskDefinition _tasks [ ] = {

In short, you have defined _tasks as a 2D array of objects (an array
of arrays of objects) while you intend to use it as a 1D array.

Note that the error message is quite explicit if you take the time to
parse it:

request for member 'task' in '_tasks[((int)i)]',

You are requesting _tasks[i].task,

which is of non-class type

but _tasks[i] is not an object.

type 'taskDefinition [4]'

It is instead an array of four taskDefinition objects.

Edit: Fixing the answer to match the latest version of the question.
Your code works, but not quite as you expect it to work. You wrote:
complexTaskDefinition tasks [ ] [4] = ...;

Here you are defining a 2D array of objects, while your intention was to
define a one-dimensional array (why do I feel like I am repeating
myself?).
complexTaskDefinition tasks [ ] [4] = {
    {taskC1, true, -1, 1000 },
    {taskC2, true, 10, 2000 },
    {taskC3, false, 3, 3000 },
};

This definition, although syntactically correct, is awfully wacky. You
are defining tasks as an array of 3 items. Each item is itself an
array of 4 objects, where the first object of the array is explicitly
initialized, and the three others are implicitly initialized to
all-bits-zero. So basically your definition is equivalent to this
explicit version:
complexTaskDefinition tasks [3] [4] = {
    {{taskC1, true, -1, 1000 }, {nullptr, false, 0, 0},
     {nullptr, false, 0, 0},    {nullptr, false, 0, 0}},
    {{taskC2, true, 10, 2000 }, {nullptr, false, 0, 0},
     {nullptr, false, 0, 0},    {nullptr, false, 0, 0}},
    {{taskC3, false, 3, 3000 }, {nullptr, false, 0, 0},
     {nullptr, false, 0, 0},    {nullptr, false, 0, 0}}
};

Then you wrote:
task = tasks [ i ];

Here, tasks[i] is a row of the 2D array, i.e. a 1D array of 4 objects,
whereas task is a pointer to object. The assignment is legit because
here, like in most contexts, the array “decays” to a pointer to its
first element. The above line is equivalent to the explicit version:
task = &tasks[i][0];

Quite fortunately, this happens to point to one of the elements of the
array that has been explicitly initialized!
As an illustration of the above, here is a modified version of
showComplexTaskList() that loops over all the tasks in the array:
void showComplexTaskList () {
    Serial.println ( F ( "\nComplex Task List:" ) );
    Serial.print(F("number of tasks: "));
    Serial.println(sizeof tasks / sizeof(complexTaskDefinition));
    for (uint8_t i = 0; i < TASK_COUNT; i++) {
        for (uint8_t j = 0; j < 4; j++) {
            task = &tasks[i][j];
            Serial.print ( '[' );
            Serial.print ( i );
            Serial.print ( F ("]["));
            Serial.print ( j );
            Serial.print ( F ( "] REPEAT:" ));
            Serial.print ( ( task->repeat ) ? "YES" : "NO" );
            Serial.print ( F ( ", DELAY:" ) );
            Serial.print ( task->delay );
            Serial.print ( F ( ", ITERATIONS:" ) );
            Serial.print ( task->iterations );
            Serial.println ();
        }
    }
}

Its output is:
Complex Task List:
number of tasks: 12
[0][0] REPEAT:YES, DELAY:1000, ITERATIONS:-1
[0][1] REPEAT:NO, DELAY:0, ITERATIONS:0
[0][2] REPEAT:NO, DELAY:0, ITERATIONS:0
[0][3] REPEAT:NO, DELAY:0, ITERATIONS:0
[1][0] REPEAT:YES, DELAY:2000, ITERATIONS:10
[1][1] REPEAT:NO, DELAY:0, ITERATIONS:0
[1][2] REPEAT:NO, DELAY:0, ITERATIONS:0
[1][3] REPEAT:NO, DELAY:0, ITERATIONS:0
[2][0] REPEAT:NO, DELAY:3000, ITERATIONS:3
[2][1] REPEAT:NO, DELAY:0, ITERATIONS:0
[2][2] REPEAT:NO, DELAY:0, ITERATIONS:0
[2][3] REPEAT:NO, DELAY:0, ITERATIONS:0

So your program works almost by chance: an error in the way you define
the array cancels an error in the way you use it. This kind of cancelled
error method is very bad programming practice. You are wasting memory in
unused complexTaskDefinition objects. More importantly, your code
doesn't express your intent, which makes the program way harder to
understand and to debug.
The fix is to declare a 1D array, as this has always been the intention:
complexTaskDefinition tasks [ ] = {
    {taskC1, true, -1, 1000 },
    {taskC2, true, 10, 2000 },
    {taskC3, false, 3, 3000 },
};

Now, you can check that this array does only have three tasks, as
reported by sizeof tasks / sizeof(complexTaskDefinition). To use the
array, you can use a pointer if you want:
task = &tasks[i];
// ...
Serial.print ( ( task->repeat ) ? "YES" : "NO" );

Or you can directly request a member of tasks[i], as in
void showComplexVersion () {
    Serial.println ( F ( "\nComplex Version:" ) );
    for (uint8_t i = 0; i < TASK_COUNT; i++) {
        tasks[i].task();
    }
}

Now I have a question for you. Since I already explained your 1D vs. 2D
array mistake in the first iteration of my answer, why did you persist
with this in your edited question? If you are going to blatantly ignore
the answers you get, at least say so in the question. This could save
time to those who might consider helping you.

I appreciate the hard work your did to explain this to me and I am learning a log. I did intend the array to be a 2D array, but my problem was with defining the task to be called within that array. I found a good post that showed me how to do that wit a callback and that worked... when the parent is the .INO file. See this post: https://arduino.stackexchange.com/questions/68299/parent-class-callback-from-child-class


text:
Communication between 2 arduino's one at 6th floor and the other at the basement
Communication between 2 Arduino's one at 6th floor and the other at the basement.
I tried with nodemcu , but the signal is not reaching the basement. From 6th floor.

Which is the best way to connect?.
I have a couple of nRF24L01 with antennas, does nRF24L01 works in this case?
How about hc-12. I have seen tests with line of sight's only.  But in this case, I have an elevation of about 80 feet and also some horizontal distance.
Basically, I wanted to implement wireless water level measurement for our overhead tank inside our apartment.
Regards
ravi

2.4 GHz radio is too short range.  Try 433 MHz modules instead.

lora will work if nothing else does. you can get ESP8266 boards with antenna jacks. using a shotgun antenna on the roof will almost assuredly connect to the basement once aimed.


text:
Reading from SD and save it in an array
I have a text file with an IR raw code that I need to read from the SD in order to send it and I don't know how to do it. I tried to use the read file function from the specific SD library but it didn't work.

irsend.sendRaw(irSignal, sizeof(irSignal) / sizeof(irSignal[0]), khz);

I want to save the code from the SD in the irSignal so I can sent it. Any ideas?
The code I've tried
#include <SPI.h>
#include <SD.h>

#include <IRremote.h>

IRsend irsend;

File myFile;

int k=0;
unsigned int irSignal[227];

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

  Serial.print("Initializing SD card...");

  if (!SD.begin(53)) {
    Serial.println("initialization failed!");
    return;
  }
  Serial.println("initialization done.");

  myFile = SD.open("sc_17.txt");
  if (myFile) {
    while (myFile.available()) {
      int val = myFile.parseInt();
      Serial.println(val);
      irSignal[k]={val};
      k++;
    }
    myFile.close();
  } else {
    // if the file didn't open, print an error:
    Serial.println("error opening dc_17.txt");
  }
}

void loop()
{
  int khz = 38;
  irsend.sendRaw(irSignal, sizeof(irSignal) / sizeof(irSignal[0]), khz); //Note the approach used to automatically calculate the size of the array.
  sendSignal();
  delay(2000); //In this example, the signal will be repeated every 5 seconds, approximately.
}

The problem is when I try to implement it in a separate function, because I need to call it for more files, it doesn't work.

What is the code you used for reading from the SD card (the read file function), and what exactly means ' it didn't work' ?

I will add the code to the question and modify it

shouldn't it be: irSignal[k]=val; ?

show the not working code

I added to the question. I put the code from the setup and the one from the loop in a separate function and it worked. Thanks !


text:
anti-theft system
I'm trying to create an anti-theft system, I use a Pir sensor for motion detection and a esp8266 to send a variable (1 or 0) to a local server with tcp protocol and at command . when I turn on the arduino it sends a 0 (no movement) but after it sends only 1 (there is a movement),
she doesn't return to the initial state.
 I tested the sensor alone, it works very well .
Any help please ?
#include<SoftwareSerial.h>
SoftwareSerial Serial1(1,0); //RX, TX
#define DEBUG true
void setup() {
   Serial1.begin(115200);
   pinMode(A0, INPUT);
   pinMode(8, OUTPUT);
}

void loop(void) {
   if(digitalRead(A0) == HIGH)
   {
      tone(8, 50);
      Serial.println("hight");
      send(1);
   }
   else
   {
      noTone(8);
      Serial.println("low");
      send(0);
   }
}

void send(int val)
{

   String rest1 = "AT+CIPMUX=1";
   rest1 += "\r\n";
   sendData(rest1, 2000, 0);

   char inv = '"';
   String add = "AT+CIPSTART";
   add += "=1,";
   add += inv;
   add += "TCP";
   add += inv;
   add += ",";
   add += inv;
   add += "192.168.46.102";  // Host_server_name
   add += inv;
   add += ",";
   add += "80";
   add += "\r\n";
   sendData(add, 3000, 0);  // Establishing a TCP Connection. ( AT+CIPSTART = "TCP","Host_server_name",80 )

   String rest = "AT+CIPSEND=1,87";
   rest += "\r\n";
   sendData(rest, 2000, 0); //Number of characters to send. ( "AT+CIPSEND=90" )

   String hostt = "GET /sp_notification/upload.php?value=";
   hostt += val;
   hostt +=" HTTP/1.1";
   hostt += "\r\n";
   hostt += "HOST:192.168.46.102";
   hostt += "\r\n\r\n\r\n\r\n\r\n";
   String views = sendData(hostt, 2000, 0);  // GET request ( GET /apps/thinghttp/send_request?api_key=XXXXXXXXXXXXXXXX
                                             //               Host: Host_server_name )
}

String sendData(String command, const int Goldout, boolean debug)
{
   String response = "";

   Serial1.print(command); // send the read character to the Serial1

   long int Gold = millis();

   while ( (Gold + Goldout) > millis())
   {
      while (Serial1.available())
      {

         // The esp has data so display its output to the serial window
         char c = Serial1.read(); // read the next character.
         response += c;
      }
   }

   if (debug)
   {
      Serial.print(response);
   }
   return response;
}

Did you try other pins? Why using an analog pin? And I assume you see never the text 'low' except during startup?

yes , i don"t see the text   , i just started using arduino i don"t know difference between pins

Does the tone stop? PS you can use \" to add a " inside a string. So for example add = "AT+CIPSTART=1,\"TCP\", ...";

A0 to A7 are analog (only) pins, the others are digital, you can try to use another pin (except 0 and 1 which are used for RX/TX UART communication), but 2 or 3 should be ok, reconnect your sensor to pin 2 or 3 too, and check if that changes.

yes , bro it s worked , but sometimes even if buzzer run he don't send (1) any suggestion ?

Gerben , when i used analogic port the tone didn"t stop

Michel Keijzers , the sensor find a great difficulty to detect my movement