Using the 'map' function as a learning exercise, not getting it right

Hi all

I have a working sketch that I am using as a basis for leaning new functions that I hope to use for future sketches. This time it is using the ‘map’ function to allocate a value between 0 and 9 to an output that goes from 0 to 65535.

The working sketch basically uses an if function to look at the output from my sim game (DCS World) for four parameters, and converts each to a single digit then makes a string that is displayed on an OLED

This is the code for that

#define DCSBIOS_DEFAULT_SERIAL

#include <DcsBios.h>
#include <Arduino.h>
#include <U8g2lib.h>
#include <Wire.h>

U8G2_SSD1306_64X32_1F_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);


char* displayString = "----";


DcsBios::Int16Buffer altPressure0Buffer(0x1086);
DcsBios::Int16Buffer altPressure1Buffer(0x1088);
DcsBios::Int16Buffer altPressure2Buffer(0x108a);
DcsBios::Int16Buffer altPressure3Buffer(0x108c);

void setup() {

  u8g2.begin();

  DcsBios::setup();
}

void loop() {
  DcsBios::loop();

  if (altPressure0Buffer.hasUpdatedData()) {
    displayString[3] = mapeo(altPressure0Buffer.getData());
  }
  if (altPressure1Buffer.hasUpdatedData()) {
    displayString[2] = mapeo(altPressure1Buffer.getData());
  }
  if (altPressure2Buffer.hasUpdatedData()) {
    displayString[1] = mapeo(altPressure2Buffer.getData());
  }
  if (altPressure3Buffer.hasUpdatedData()) {
    displayString[0] = mapeo(altPressure3Buffer.getData());
  }

  u8g2.clearBuffer();
  u8g2.setFont(u8g2_font_fub20_tn );
  u8g2.setCursor(0, 24);
  u8g2.print(displayString);
  u8g2.sendBuffer();

  delay (10);

}

char mapeo(unsigned int valor) {

  if (valor < 6553) {
    return '0';
  }
  if ((valor >= 6553) && (valor < 13107)) {
    return '1';
  }
  if ((valor >= 13107) && (valor < 19660)) {
    return '2';
  }
  if ((valor >= 19660) && (valor < 26214)) {
    return '3';
  }
  if ((valor >= 26214) && (valor < 32767)) {
    return '4';
  }
  if ((valor >= 32767) && (valor < 39321)) {
    return '5';
  }
  if ((valor >= 39321) && (valor < 45874)) {
    return '6';
  }
  if ((valor >= 45874) && (valor < 52428)) {
    return '7';
  }
  if ((valor >= 52428) && (valor < 58981)) {
    return '8';
  }
  return '9' ;

}

I used CTRL + T to format the code

I tried a sketch with an LCD display to see if I can make the ‘map’ function work, and I seem to be able to do so but only as individually printed numbers, however I want to display it as a string, as per the first working sketch.

The new sketch uses the ‘map’ function, and compiles fine but just doesn’t display the characters, it only displays the " ---- " characters as defined in the line

char* displayString = "----";

So I obviously have the syntax wrong for this particular sketch, code below

#define DCSBIOS_DEFAULT_SERIAL

#include <DcsBios.h>
#include <Arduino.h>
#include <U8g2lib.h>
#include <Wire.h>

U8G2_SSD1306_64X32_1F_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);

char* displayString = "----";


void onAltPressure0Change(unsigned int newValue0) {

  displayString[0] = map(newValue0, 0, 65535, 0, 9);
  

}
DcsBios::IntegerBuffer altPressure0Buffer(0x1086, 0xffff, 0, onAltPressure0Change);

void onAltPressure1Change(unsigned int newValue1) {

  displayString[1] = map(newValue1, 0, 65535, 0, 9);
  

}
DcsBios::IntegerBuffer altPressure1Buffer(0x1088, 0xffff, 0, onAltPressure1Change);

void onAltPressure2Change(unsigned int newValue2) {

  displayString[2] = map(newValue2, 0, 65535, 0, 9);
  

}
DcsBios::IntegerBuffer altPressure2Buffer(0x108a, 0xffff, 0, onAltPressure2Change);


void onAltPressure3Change(unsigned int newValue3) {

  displayString[3] = map(newValue3, 0, 65535, 0, 9);
  

}
DcsBios::IntegerBuffer altPressure3Buffer(0x108c, 0xffff, 0, onAltPressure3Change);


void setup() {

  u8g2.begin();


  u8g2.clearBuffer();
  u8g2.setFont(u8g2_font_fub20_tn );
  u8g2.setCursor(0, 24);
  u8g2.print(displayString);
  u8g2.sendBuffer();

  delay (10);

  DcsBios::setup();
}

void loop() {
  DcsBios::loop();



  delay (10);

}

It’s obvious that I have placed some of the sketch in the wrong section or the wrong order. The thing is, I want to understand why it is wrong, not just have it working. In fact, having it working is not the aim, it is to learn how to write sketches. 99% of what I write is or will be for the DSC World game, hence me using this a an example, but I clearly am missing some mental leap that allows me to comprehend the needed structure.

I’ve read up lots of ‘tutorials’ and help pages, the problem is with them is that because you are following a scripted example, it doesn’t teach you how to avoid the issues, whereas a live example like this does in a more proactive way.

So if there is an (understandable) explanation of what is wrong, I am happy to try and digest it and see if I can correct it on my own, if you can be a little patient with me!

Thanks in advance for any help given

Les

You're mapping correctly but you are then mixing up int and char. You will get an integer value between 0 and 9, but what you want is a char value between '0' and '9' which isn't the same thing. Try adding 48 to the value you get from the map.

Thanks, will try that

Just to understand, why would adding 48 to the value convert it from an integer to a character, what's the philosophy behind that.

And a knock on question, as I'm trying to think about this - would the itoa function do the job of converting the integers to characters?

maybe this?

itoa (Value0,displayString[0],10);

Cheers

Les

It happens that in ASCII, the int 48 represents the char '0', ... , the int 57 represents the char '9'.

It is probably sufficient to replace 0 with '0' and 9 with '9' in your map(...) function calls but I have not tested this.

I expect the compiler to handle the lengthening from a char to an int. It will be interesting to see that this is the case.

Characters are eight (or seven if you're talking strict ASCII) bit quantities that are used to represent the letters and numbers that you show on a display or monitor.

The letter 'A' is actually represented by the number 65. Zero ('0') is 48. Characters with values under 32 are generally regarded as non printable and those are what you were putting in your display string. That's why you need to add 48.

Itoa won't really help you here.