How to combine Data acquisition and use a tone to indicate height.

My intention is to receive an altitude value in feet via a HC12 seriel TRX (this parts works well) and then via a piezo buzzer, indicate the height using the buzzer. i.e. 1 buzz for 100 feet and then 2 buzzes for 200 feet etc. upto 800 feet. The code I try to use is below and I have a problem as follows:

  1. when I switch the RX on the buzzer sounds even when the value is under that which I have setup. I have tried adding a vale where there is noTone but this does not seem to work.
  2. The changing value of the height (receivedChars) is not reflected on the Oled which I presume means that the loop does not get that far.
    I am showing the code as it works with just the Oled value, this shows changes in height OK. When I add the blanked out code for the Tone then the problems start as described.
    What I would really like to do is call the values of receivedChar when the tone has finished, but i am not sure how to go about this.
//HC12_BME280_paul_altitude_RX_V1_23_03_2018_works

const byte numChars = 32;
char receivedChars[numChars];
boolean newData = false;
#include <SoftwareSerial.h>;
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
int piezoPin = 4;
#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);
SoftwareSerial mySerial(2, 3); // RX, TX
void setup() {
  Serial.begin(9600);
  mySerial.begin(9600);
  pinMode(7, OUTPUT);
  digitalWrite(7, LOW);
  mySerial.print(F("AT+C001\r\n"));
  delay(100);
  digitalWrite(7, HIGH);
  display.begin(SSD1306_SWITCHCAPVCC, 0x3c);  // initialize with the I2C addr 0x3D (for the 128x64)
  noTone(piezoPin);
}
void loop() {
  recvWithStartEndMarkers();
  showNewData();
/*  if (receivedChars <= 400)
  {
    noTone(piezoPin);
  }
  else if  (receivedChars >= 400 && receivedChars <= 450)
  {
    tone(piezoPin, 3000, 200);
    delay(1000);
    tone(piezoPin, 3000, 200);
    delay(1000);
  }
  if (receivedChars <= 400)
  {
    noTone(piezoPin);
  }

  else if  (receivedChars >= 800)
  {
    tone(piezoPin, 3000, 200);
    delay(1000);
    tone(piezoPin, 3000, 200);
    delay(1000);
    tone(piezoPin, 3000, 200);
    delay(1000);
  }
  if (receivedChars <= 400)
  {
    noTone(piezoPin);
  }
*/
  noTone(piezoPin);
  display.clearDisplay();
  display.setTextSize(2);
  display.setTextColor(WHITE);
  display.setCursor(20, 1);
  display.println("Altitude");
  display.setCursor(20, 20);
  display.println("in Feet");
  display.setTextSize(2);
  display.setCursor(55, 50);
  display.println(receivedChars);
  display.display();
  noTone(piezoPin);

  /*  else {
    (tone(piezoPin, 3000)); // tone erzeugung
    delay(2000);
    display.clearDisplay();
    display.setTextSize(2);
    display.setTextColor(WHITE);
    display.setCursor(20, 1);
    display.println("Switch");
    display.setCursor(40, 25);
    display.println("TX");
    display.setCursor(30, 50);
    display.println("ON!!!");
    display.display();

    {
  */

}

void recvWithStartEndMarkers() {
  static boolean recvInProgress = false;
  static byte ndx = 0;
  char startMarker = '<';
  char endMarker = '>';
  char rc;

  while (mySerial.available() > 0 && newData == false) {
    rc = mySerial.read();

    if (recvInProgress == true) {
      if (rc != endMarker) {
        receivedChars[ndx] = rc;
        ndx++;
        if (ndx >= numChars) {
          ndx = numChars - 1;
        }
      }
      else {
        receivedChars[ndx] = '\0'; // terminate the string
        recvInProgress = false;
        ndx = 0;
        newData = true;
      }
    }

    else if (rc == startMarker) {
      recvInProgress = true;
    }
  }
}

void showNewData() {
  if (newData == true) {
    Serial.print("Height in Feet =  ");
    Serial.println(receivedChars);
    newData = false;
  }
}
int piezoPin = 4;
#define OLED_RESET 4

It’s rarely possible to use one pin for two different purposes.

  pinMode(7, OUTPUT);

Magic numbers suck. Assign a name to pin7 (No, not pin7), so we have a clue what pin 7 is being used for.

SoftwareSerial mySerial(2, 3); // RX, TX

Please post a picture of the mySerial that you connected to these two pins.

What I would really like to do is call the values of receivedChar

You call functions, not values. receivedChar is a string. A string is ONE value. The string MIGHT be a representation of numerical values (“45, 2, 34”) or not (“Tom, Dick, and Harry”).

Your commented out code is comparing the address of the array to 400, 450, etc. That hardly makes sense.

It is clear that the code started from Robin2’s tutorial, but that you did NOT read the tutorial to the end.

  1. when I switch the RX on the buzzer sounds even when the value is under that which I have setup. I have tried adding a vale where there is noTone but this does not seem to work.

See the comment about comparing the address of the array.

  1. The changing value of the height (receivedChars) is not reflected on the Oled which I presume means that the loop does not get that far.

The code assumes that the sender is sending something like “<425>”. Is it? Debugging by guesswork sucks, doesn’t it? So, why ARE you?

Serial.print() each character received, so you KNOW what you are getting.

PaulS:

int piezoPin = 4;

#define OLED_RESET 4



It's rarely possible to use one pin for two different purposes.



pinMode(7, OUTPUT);



Magic numbers suck. Assign a name to pin7 (No, not pin7), so we have a clue what pin 7 is being used for.



SoftwareSerial mySerial(2, 3); // RX, TX



Please post a picture of the mySerial that you connected to these two pins.
You call functions, not values. receivedChar is a string. A string is ONE value. The string MIGHT be a representation of numerical values ("45, 2, 34") or not ("Tom, Dick, and Harry").

Your commented out code is comparing the address of the array to 400, 450, etc. That hardly makes sense.

It is clear that the code started from Robin2's tutorial, but that you did NOT read the tutorial to the end.
See the comment about comparing the address of the array.
The code assumes that the sender is sending something like "<425>". Is it? Debugging by guesswork sucks, doesn't it? So, why ARE you?

Serial.print() each character received, so you KNOW what you are getting.

OK I will go through your comments. The pins 2,3 are attached to the HC12. I will post a foto of the wires if you really want but the data is being received OK because as I said the OLED shows to height ok when the Tone stuff is not switched on. The problem with Char etc. is most likely the cause of the problem but I don’t know how to convert the Char to Float numbers, if that is at all possible. I will start by reading Robin2’s tutorial again, I must have missed something. In he mean time thanks.

The pins 2,3 are attached to the HC12. I will post a foto of the wires if you really want

So, it is NOT a mySerial that is connected to the pins. Why the hell do you have such a stupid name for the instance, then?

Wouldn't it make a lot more sense to do HC12.read() or HC12.print()?

I don't know how to convert the Char to Float numbers, if that is at all possible.

atof() to convert a string to a float. atoi() to convert a string to an int.

PaulS: So, it is NOT a mySerial that is connected to the pins. Why the hell do you have such a stupid name for the instance, then?

Wouldn't it make a lot more sense to do HC12.read() or HC12.print()? atof() to convert a string to a float. atoi() to convert a string to an int.

The HC12 is a TRX board for serial data, basically it is a serial connection that has a range of over 1 KM. The definition of the pins is from the example of the HC12, sorry if it is confusing..

I will try converting the Chars to float, and see if the things run better.

Thank you very much for your help PaulS. Works fine now. I hope you could give me a suggestion how I could do the beeps according to the height. ie. one beep for 100 feet and then 2 beeps for 200 feet up to 800 feet. Is there a clean way of writing the code or do I have to write the tone 8 times for 800 feet etc. Hope you understand what I mean. I have really learned alot in the last month on this forum.

Is there a clean way of writing the code or do I have to write the tone 8 times for 800 feet etc.

If you can beep once, you can create a for loop that iterates n times. Put the beep code in that for loop, to beep n times.

THANK YOU: Have a nice day. :-)