Нужно удвоить форматы sprintf и вернуть слишком длинную строку - PullRequest
0 голосов
/ 30 апреля 2018

(Это модифицированная паста из: https://forum.arduino.cc/index.php?topic=544603.msg3711704)

Во-первых, вот мой код:

//#include <RCSwitch.h>
#include <EEPROM.h>

#define deviceSerial 1

//RCSwitch mySwitch = RCSwitch();

int button1 = PB2;
int button2 = PB1;
int button3 = PB0;

int radio = PB3;
int keepalive = PB4;

int i = 0;

unsigned long long intToBin(unsigned int k) {
    return (k == 0 || k == 1 ? k : ((k % 2) + 10 * intToBin(k / 2)));
}

unsigned int nextCode(){
  // Get current occurrence
  int occurrence = getOccurrence();
  // Increment occurrence
  // Commented out to preserve EEPROM at the moment
  //incrementOccurrence();
  *censored code*
  return *censored code but returns an int*
}

int getOccurrence(){
  return (EEPROM.read(0) + EEPROM.read(1) + EEPROM.read(2) + EEPROM.read(3));
}

void incrementOccurrence(){
  int occurrence = getOccurrence() + 1;
  if(occurrence >= 1020){
    //reset
    EEPROM.write(0, 1);
    EEPROM.write(1, 0);
    EEPROM.write(2, 0);
    EEPROM.write(3, 0);
  }
  else if (occurrence >= 765){
    EEPROM.write(0, 255);
    EEPROM.write(1, 255);
    EEPROM.write(2, 255);
    EEPROM.write(3, occurrence - 765);
  }
  else if (occurrence >= 510){
    EEPROM.write(0, 255);
    EEPROM.write(1, 255);
    EEPROM.write(2, occurrence - 510);
    EEPROM.write(3, 0);
  }
  else if (occurrence >= 255){
    EEPROM.write(0, 255);
    EEPROM.write(1, occurrence - 255);
    EEPROM.write(2, 0);
    EEPROM.write(3, 0);
  }
  else {
    EEPROM.write(0, occurrence);
    EEPROM.write(1, 0);
    EEPROM.write(2, 0);
    EEPROM.write(3, 0);
  }
}

void transmit(int button){
  char message[33];
  sprintf(message, "%014lu%lu%016lu%lu%02lu", intToBin(deviceSerial), intToBin(nextCode()), intToBin(button)); <---------------
  //mySwitch.send(message);
}

void setup() {
  pinMode(keepalive, OUTPUT);
  digitalWrite(keepalive, HIGH);

  pinMode(button1, INPUT);
  pinMode(button2, INPUT);
  pinMode(button3, INPUT);

  //mySwitch.enableTransmit(radio);

  if(digitalRead(button1) == 1){
    transmit(1);
  }
  if(digitalRead(button2) == 1){
    transmit(2);
  }
  if(digitalRead(button3) == 1){
    transmit(3);
  }

  // Self shutdown
  digitalWrite(PB4, LOW);
}

void loop() {
}

Текущие выходы (разделенные значения):

0000000000000100000001011010010010 (00000000000001 0000000101101001 0010)

Где это должно быть (разделенные значения):

00000000000001000000010110100110 (00000000000001 0000000101101001 10)

Моя проблема заключается в том, что я пытаюсь получить все переменные для отправки сообщения.

  • Зачем мне удваивать %lu?
  • Почему полученная строка равна 34 символам, когда я объявил 33 (32 + \ 0)? Последний длинный 4 вместо двух (0010 вместо 10)

Странная вещь:

sprintf(message, "%016lu", intToBin(nextCode())); // Works correctly
sprintf(message, "%014lu", intToBin(deviceSerial)); // Works correctly
sprintf(message, "%02lu", intToBin(button)); //Works correctly

1 Ответ

0 голосов
/ 30 апреля 2018

Ваша функция

unsigned long long intToBin(unsigned int k)

но ваши спецификаторы формата %lu. Манекен %lu «работает», выравнивая данные.

Пожалуйста, используйте правильный спецификатор формата %llu.

РЕДАКТИРОВАТЬ: %llu не поддерживается. Вы успешно использовали:

sprintf(message, "%016lu", intToBin(nextCode())); // Works correctly
sprintf(message, "%014lu", intToBin(deviceSerial)); // Works correctly
sprintf(message, "%02lu", intToBin(button)); //Works correctly

Предлагаемое исправление для сборки message:

int len;
len  = sprintf(message,       "%016lu", intToBin(nextCode()));
len += sprintf(message + len, "%014lu", intToBin(deviceSerial));
       sprintf(message + len, "%02lu",  intToBin(button));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...