How to store value into unsigned char array [SOLVED]

Hi guys,

So, I am doing a LEDs Pixel Display now, using 100 WS2811 LEDs, FastLED and LEDText libraries.
FastLED: GitHub - FastLED/FastLED: The FastLED library for colored LED animation on Arduino. Please direct questions/requests for help to the FastLED Reddit community: http://fastled.io/r We'd like to use github "issues" just for tracking library bugs / enhancements.
LEDText: GitHub - AaronLiddiment/LEDText: FastLED Flexible Text Message Class requires LEDMatrix Class

One of the functions of the display is to show temperature and weather description. I am using LEDText library for the scrolling effect and unsigned char array is needed for it.

if (ScrollingMsg.UpdateText() == -1)
        ScrollingMsg.SetText((unsigned char *)connecting, sizeof(connecting) - 1);
      else
        FastLED.show();
      delay(100);

Well, cause I am just started so I am only trying to display the temperature for now. The getting data from web part is OK, data showed up on the serial monitor.

My problem is, I can't manage to make the result to show up on the display. I suspect that there is some problem with the display function.

This is the part that I think where the problem is,
*There is comment label with no.1,2 and 3, is the 3 approaches I have tried.

void displayWeather(float Temperature)
{      
      //the 3 approaches I have tried
      //no.1
      unsigned char a = (unsigned char)Temperature;
      //result: only serial monitor display the result

      //no.2
      unsigned char a[sizeof(Temperature)];
      memcpy(a, &Temperature, sizeof(Temperature));
      //result: call of overloaded 'println(unsigned char [4])' is ambiguous

      //for no.1 and no.2
      ScrollingMsg.SetText((unsigned char *)a, sizeof(a) - 1);
      for(int x=0;x<((sizeof(a))*6);x++)
      {
          if (ScrollingMsg.UpdateText() == -1)
            ScrollingMsg.SetText((unsigned char *)a, sizeof(a) - 1);
          else
            FastLED.show();
          delay(100);
      }
      //Serial(57600)
      Serial.println(a);
}

As you can see, I focus on to change the float to unsigned char array cause I thought it doesn't display on the screen because the ScrollingMsg is not getting the value. So I am thinking is it the converting problem(but it did show up on the serial monitor means it success to convert?) or is it because the unsigned char a is not an array?
Do you have any idea why is it like that and how can I solve this?

Thanks in advance!!!

*Below is the full code

The full code

#include <ESP8266WiFi.h>
#include <ArduinoJson.h>
//display
#include <FastLED.h>
#include <LEDMatrix.h>
#include <LEDText.h>
#include <FontMatrise.h>

#define LED_PIN        3
#define COLOR_ORDER    RGB
#define CHIPSET        WS2811
#define MATRIX_WIDTH   10
#define MATRIX_HEIGHT  10
#define MATRIX_TYPE    VERTICAL_ZIGZAG_MATRIX

cLEDMatrix<MATRIX_WIDTH, MATRIX_HEIGHT, MATRIX_TYPE> leds;
cLEDText ScrollingMsg;

const char* ssid     = "ssid";      // SSID of local network
const char* password = "pwd";   // Password on network
String APIKEY = "apikey";
String CityID = "xxxxxx"; 

WiFiClient client;
char servername[]="api.openweathermap.org";  // remote server we will connect to
String result;

int  counter = 30;

//String weatherDescription = "";
//String weatherLocation = "";
//String Country;
float Temperature;
//float Humidity;
//float Pressure;

//display
unsigned char connecting[] = "  connecting ";
unsigned char conn[] = "  connected  ";
unsigned char getting[] = "  getting data ";
unsigned char connfail[] = "  connection failed ";
unsigned char parsefail[] = "  parseObject() failed ";

void setup() {
  //Serial(57600)
  Serial.begin(57600);
  //display
  FastLED.addLeds<CHIPSET, LED_PIN, COLOR_ORDER>(leds[0], leds.Size());
  FastLED.setBrightness(100);
  FastLED.clear(true);
  delay(500);
  ScrollingMsg.SetFont(MatriseFontData);
  ScrollingMsg.Init(&leds, leds.Width(), ScrollingMsg.FontHeight() + 1, 0, 1);
  ScrollingMsg.SetText((unsigned char *)connecting, sizeof(connecting) - 1);

  //display "connecting"
  for(int x=0;x<(sizeof(connecting)*6);x++)
  {
      if (ScrollingMsg.UpdateText() == -1)
        ScrollingMsg.SetText((unsigned char *)connecting, sizeof(connecting) - 1);
      else
        FastLED.show();
      delay(100);
  }
  
  WiFi.begin(ssid, password);

  //display "connecting"
  while (WiFi.status() != WL_CONNECTED) {
      //Serial(57600)
      Serial.print(".");
      if (ScrollingMsg.UpdateText() == -1)
        ScrollingMsg.SetText((unsigned char *)connecting, sizeof(connecting) - 1);
      else
        FastLED.show();
      delay(100);
  }
  
  //display "connected" 
  ScrollingMsg.SetText((unsigned char *)conn, sizeof(conn) - 1);
  for(int x=0;x<(sizeof(conn)*6);x++)
  {
      if (ScrollingMsg.UpdateText() == -1)
        ScrollingMsg.SetText((unsigned char *)conn, sizeof(conn) - 1);
      else
        FastLED.show();
      delay(100);
  }
  //Serial(57600)
  Serial.println("connected");
  delay(1000);
}

void loop() {
    if(counter == 30) //Get new data every 5 minutes
    {
        counter = 0;
        displayGettingData();
        delay(1000);
        getWeatherData();
    }
    else
    {
        counter++;
        displayWeather(Temperature);
        delay(5000);
    }
}

void getWeatherData() //client function to send/receive GET request data.
{
  if (client.connect(servername, 80)) //starts client connection, checks for connection
  {  
      client.println("GET /data/2.5/weather?id="+CityID+"&units=metric&APPID="+APIKEY);
      client.println("Host: api.openweathermap.org");
      client.println("User-Agent: ArduinoWiFi/1.1");
      client.println("Connection: close");
      client.println();
  } 
  else 
  {
      //display "connection failed"
      ScrollingMsg.SetText((unsigned char *)connfail, sizeof(connfail) - 1);
      for(int x=0;x<(sizeof(connfail)*6);x++)
      {
          if (ScrollingMsg.UpdateText() == -1)
            ScrollingMsg.SetText((unsigned char *)connfail, sizeof(connfail) - 1);
          else
            FastLED.show();
          delay(100);
      }
  }

  while(client.connected() && !client.available())
  {
      delay(1); //waits for data
  }
  while (client.connected() || client.available()) //connected or data available
  { 
      char c = client.read(); //gets byte from ethernet buffer
      result = result+c;
  }
  client.stop(); //stop client
  result.replace('[', ' ');
  result.replace(']', ' ');
  ////
  Serial.println(result);

  char jsonArray [result.length()+1];
  result.toCharArray(jsonArray,sizeof(jsonArray));
  jsonArray[result.length() + 1] = '\0';
  
  StaticJsonBuffer<1024> json_buf;
  JsonObject &root = json_buf.parseObject(jsonArray);
  if (!root.success())
  {
      //display "parseObject() failed"
      ScrollingMsg.SetText((unsigned char *)parsefail, sizeof(parsefail) - 1);
      for(int x=0;x<(sizeof(parsefail)*6);x++)
      {
          if (ScrollingMsg.UpdateText() == -1)
            ScrollingMsg.SetText((unsigned char *)parsefail, sizeof(parsefail) - 1);
          else
            FastLED.show();
          delay(100);
      }
  }
  
//  String location = root["name"];
//  String country = root["sys"]["country"];
  float temperature = root["main"]["temp"];
//  float humidity = root["main"]["humidity"];
//  String weather = root["weather"]["main"];
//  String description = root["weather"]["description"];
//  float pressure = root["main"]["pressure"];
  
//  weatherDescription = description;
//  weatherLocation = location;
//  Country = country;
    Temperature = temperature;
    //Serial(57600)
    Serial.println(Temperature);
//  Humidity = humidity;
//  Pressure = pressure;

}

void displayWeather(float Temperature)
{      
      //no.1
      unsigned char a = (unsigned char)Temperature;
      //result: only serial monitor display the result

      //no.2
      unsigned char a[sizeof(Temperature)];
      memcpy(a, &Temperature, sizeof(Temperature));
      //result: call of overloaded 'println(unsigned char [4])' is ambiguous

      //for no.1 and no.2
      ScrollingMsg.SetText((unsigned char *)a, sizeof(a) - 1);
      for(int x=0;x<((sizeof(a))*6);x++)
      {
          if (ScrollingMsg.UpdateText() == -1)
            ScrollingMsg.SetText((unsigned char *)a, sizeof(a) - 1);
          else
            FastLED.show();
          delay(100);
      }
      //Serial(57600)
      Serial.println(a);

      //no.3
      //Serial(57600)
      Serial.println(Temperature);
      Serial.println(sizeof(Temperature));
      unsigned char a[sizeof(Temperature)] = {};
      for(int j=0;j<1;j++){
            a[j] = (unsigned char)Temperature;
            //Serial(57600)
            Serial.println(a[j]);
            Serial.println(sizeof(a[j]));
            //display temperature
            ScrollingMsg.SetText((unsigned char *)a[j], sizeof(a[j]) - 1);
            for(int x=0;x<((sizeof(a[j]))*6);x++)
            {
                if (ScrollingMsg.UpdateText() == -1)
                  ScrollingMsg.SetText((unsigned char *)a[j], sizeof(a[j]) - 1);
                else
                  FastLED.show();
                delay(100);
            }
      }
    //result: only serial monitor display result
}

void displayGettingData()
{
  //display getting data
  ScrollingMsg.SetText((unsigned char *)getting, sizeof(getting) - 1);
  for(int x=0;x<(sizeof(getting)*6);x++)
  {
    if (ScrollingMsg.UpdateText() == -1)
      ScrollingMsg.SetText((unsigned char *)getting, sizeof(getting) - 1);
    else
      FastLED.show();
    delay(100);
  }
  //Serial(57600)
  Serial.println("getting data");
}

You need to convert your float to a C string. Take a look at dtostrf.

Keep in mind that you can NOT convert a float to a char, signed or not.

You can convert a float to a char ARRAY, using dtorstrf() as wildbill suggests.

It is VERY important that you understand the difference between a char and a char array, and use the correct term.

Sure, I will try dtostrf(). Thanks!

So I just have to change float to char array and to unsigned char array, is it correct?

Hi, Thanks guys, it solved!

void displayWeather(float Temperature, String weatherDescription)
{    
    //Temperature
    char dest1[TEMPBUFSZ] = "  "; //set space in front for scroll
    char src1[TEMPBUFSZ]; //to store Temperature
    dtostrf(Temperature, 5, 2, src1); //convert float to char array
    strcat(dest1,src1); //concat dest1 and src1 "  99.99" to dest1
    strcat(dest1,"C"); //concat dest1 and "C" "  99.99C" to dest1
    unsigned char temp[TEMPBUFSZ] = "";  //create unsigned char array
    strcpy ((char*)temp, dest1); //convert char array dest1 to unsigned char array temp

    //weatherDescription
    char dest2[DESCBUFSZ] = "  "; //set space in front for scroll
    char src2[DESCBUFSZ]; //to store description
    weatherDescription.toCharArray(src2,DESCBUFSZ); //convert String to char array
    strcat(dest2,src2); //concat dest2 and src2 "  description" to dest2
    unsigned char desc[DESCBUFSZ] = "";  //create unsigned char array
    strcpy ((char*)desc, dest2); //convert char array dest2 to unsigned char array desc

    //Serial(57600)
    Serial.println(dest1);
    Serial.println(dest2);
    
    //display temperature
    ScrollingMsg.SetText((unsigned char *)temp, sizeof(temp) - 1);
    for(int x=0;x<((sizeof(temp))*6);x++)
    {
        if (ScrollingMsg.UpdateText() == -1)
          ScrollingMsg.SetText((unsigned char *)temp, sizeof(temp) - 1);
        else
          FastLED.show();
        delay(200);
    }

    //display description
    ScrollingMsg.SetText((unsigned char *)desc, sizeof(desc) - 1);
    for(int x=0;x<((sizeof(desc))*6);x++)
    {
        if (ScrollingMsg.UpdateText() == -1)
          ScrollingMsg.SetText((unsigned char *)desc, sizeof(desc) - 1);
        else
          FastLED.show();
        delay(200);
    }
}

There is no need to copy the char array to an unsigned char array. You can cast a char array to an unsigned char array.

Once you have copied the data from the array that dtostrf() wrote to, you can reuse that array. You don't need to create another array.

You should be doing defensive programming. BEFORE copying a string to an another string, make sure that there is room in the destination string for the data in the source string.

PaulS:
There is no need to copy the char array to an unsigned char array. You can cast a char array to an unsigned char array.

Once you have copied the data from the array that dtostrf() wrote to, you can reuse that array. You don't need to create another array.

You should be doing defensive programming. BEFORE copying a string to an another string, make sure that there is room in the destination string for the data in the source string.

Hi PaulS,

Are you saying something like this?

char dest1[TEMPBUFSZ] = "  "; //set space in front for scroll
    char src1[TEMPBUFSZ]; //to store Temperature
    dtostrf(Temperature, 4, 1, src1); //convert float to char array
    strcat(dest1,src1); //concat dest1 and src1 "  99.99" to dest1
    strcat(dest1,"C"); //concat dest1 and "C" "  99.99C" to dest1
    unsigned char *temp = (unsigned char *)dest1;

Are you saying something like this?

You do NOT need:

    unsigned char *temp = (unsigned char *)dest1;

Wherever you use temp, use (unsigned char *)dest1 instead.