непонятки с PROGMEM

M@@}{

✩✩✩✩✩✩✩
5 Май 2021
7
0
Доброго времени суток уважаемые форумчане.
использую стандартную среду ардуино иде для х86 системы, контроллер Ардуино нано 8 мг

Столкнулся я с такой проблемой:
работая в классе изначально создаю массив структур и записываю его в память при прошивке, во таким способом

C++:
struct listOperator
{
  const char operatorName[LONGOPERATORNAME];
  const char operatorUSSD[LONGUSSDOPERATOR];
  const char firstSymbol;
  const char endSymb;
  const int stepFirst;
  //  const char phonePDU[13];
  //  const char plot[9];
};


const listOperator PROGMEM Operator[] =
{
  { "UNCNOW",  "UNCNOW",                  0x3A, '4' , 1 },
  { "MTS",     "AT+CUSD=1,\"*100#\" ", ':',  0xD1, 1 },
  { "TELE2",   "AT+CUSD=1,\"*105#\" ", 0x3A, 0xD1, 1 },
  { "BEELINE", "AT+CUSD=1,\"*102#\" ", 0x3A, 0xD1, 1 },
  { "MEGAFON", "AT+CUSD=1,\"*100#\" ", '\0', 0xD1, 1 },
  { '\0', '\0', '\0', '\0', '\0'}
  //{ NULL, NULL, NULL, NULL, NULL}
};
далее через элементы класса пытаюсь вывести на печать все элементы структур

C++:
int SIM800E :: GetIdOperator(const char* _opertor)
{
  int i = 0;
  while (strlen_P(Operator[i].operatorName) != 0)
  {
    if (strcmp_P(_opertor, Operator[i].operatorName) == 0) {
      Serial.print(i, DEC);
      return i;
    }
    i++;
  }
  return 0xFF;
}


char* SIM800E :: GetOperatorToId(int _id)
{
  static char _OperatorName [LONGOPERATORNAME + 1] = "";
  strcpy_P(_OperatorName, Operator[_id].operatorName);
  return _OperatorName;
}

char* SIM800E :: GetUSSDToId(int _id)
{
  static char USSDOperator [LONGUSSDOPERATOR + 1] = "";
  strcpy_P(USSDOperator, Operator[_id].operatorUSSD);
  return USSDOperator;
}

char SIM800E :: GetFirstSymbol(int _id)
{
  static char FirstSymbol  = '\0';
  FirstSymbol = pgm_read_byte(&(Operator[_id].firstSymbol));
  return FirstSymbol;
}

char SIM800E :: GetEndSymbol(int _id)
{
  char EndSymbol  = '\0'; // static
  char Symbol  = '\0';
  //EndSymbol = pgm_read_byte(&Operator[_id].endSymbol);
  Symbol = pgm_read_byte(&(Operator[_id].endSymb));
  EndSymbol = (char)Symbol & 0xFF;

  return EndSymbol;
}

int SIM800E :: GetStepFirst(int _id)
{
  static int StepFirst  = 0;
  StepFirst = pgm_read_byte(&Operator[_id].stepFirst);

  return (int)StepFirst;
}
вот таким циклом:

C++:
while (strlen (Sim.GetOperatorToId(icount)) != 0){
  Serial.print(F("Operator - "));
  Serial.print(icount,DEC);
  Serial.print(F("\t "));
  Serial.print(Sim.GetOperatorToId(icount));
  Serial.print(F("; GetUSSD -  "));
  Serial.print(Sim.GetUSSDToId(icount));
  Serial.print(F("\t; GetFirst - "));
  Serial.print((char)Sim.GetFirstSymbol(icount),HEX);
  Serial.print(F("\t; GetEnd -  "));
  Serial.print((char)Sim.GetEndSymbol(icount),HEX);
  Serial.print(F("\t; GetStep - "));
  Serial.println(Sim.GetStepFirst(icount),DEC);
  icount++;
  }
}
а контроллер выводит в монитор не то что я хочу видеть:
List operator:
Operator - 0 UNCNOW; GetUSSD - UNCNOW ; GetFirst - 3A ; GetEnd - 34 ; GetStep - 1
Operator - 1 MTS; GetUSSD - AT+CUSD=1,"*100#" ; GetFirst - 3A ; GetEnd - FFFFFFD1 ; GetStep - 1
Operator - 2 TELE2; GetUSSD - AT+CUSD=1,"*105#" ; GetFirst - 3A ; GetEnd - FFFFFFD1 ; GetStep - 1
Operator - 3 BEELINE; GetUSSD - AT+CUSD=1,"*102#" ; GetFirst - 3A ; GetEnd - FFFFFFD1 ; GetStep - 1
Operator - 4 MEGAFON; GetUSSD - AT+CUSD=1,"*100#" ; GetFirst - 0 ; GetEnd - FFFFFFD1 ; GetStep - 1

так вот вопрос к знатокам почему при одинаковом объявлении GetFirst - читается правильно а GetEnd выводит в порт какуюто ересь???

пример кода прилагается!

Это выжимка из проекта по крупнее.
 

Вложения

Сотнег

★★★★★★★
15 Янв 2020
4,316
1,482
@M@@}{,
нету никакой ереси.
Потому что 0xD1 - это не char, а в лучшем случае byte.
 

M@@}{

✩✩✩✩✩✩✩
5 Май 2021
7
0
@Сотнег,

почему в одном случае данные читаются правильно например 3A а в случае где должно быть D1 я вижу FFFFFFD1
в hex я должен увидеть D1, не важно это char или byte контроллер то 8bit, оба этих типа данных 1байт 8 бит.
 

Сотнег

★★★★★★★
15 Янв 2020
4,316
1,482
@M@@}{,
ну, так ведь 0x3A - это вполне себе char.
Вы диапазоны используемых типов смотрели?
Битов по 8, а диапазоны разные.
 

Bruzzer

★★★✩✩✩✩
23 Май 2020
453
131
где должно быть D1 я вижу FFFFFFD1
Потому, что при Serial.print происходит внутреннее промежуточное преобразование в long
А так как char это знаковый тип, то значение D1 трактуется как отрицательное число и преобразуется в FFFFFFD1
Если бы тип был без знаковый (например byte) то D1 преобразуется в D1