Объединить две одинаковые функции с разными аргументами

DarkDaemon
Offline
Зарегистрирован: 31.10.2015

Есть две похожие функции, одна принимает в качестве аргумента указатель на char, другая - на byte. Код у них абсолютно одинаковый. Как сделать из двух функций одну универсальную функцию?

 

void m24m01read(unsigned long addr, byte* data, uint8_t nRead){
  uint8_t ctrlByte = 0x50 | (byte) (addr >> 16);
  Wire.beginTransmission(ctrlByte);
  Wire.write((byte)(addr >> 8));
  Wire.write((byte)(addr));
  Wire.endTransmission();
  Wire.requestFrom(ctrlByte, nRead);
  byte i = 0;
    while(Wire.available()){ 
      data[i] = Wire.read();
      i++;
    }
  }
}


void m24m01readstring(unsigned long addr, char* data, uint8_t nRead) {
  uint8_t ctrlByte = 0x50 | (byte) (addr >> 16);
  Wire.beginTransmission(ctrlByte);
  Wire.write((byte)(addr >> 8)); 
  Wire.write((byte)(addr)); 
  Wire.endTransmission();
  Wire.requestFrom(ctrlByte, nRead);
  byte i = 0;
  while(Wire.available()){ 
    data[i] = Wire.read();
    i++;
  }
}

 

 

Logik
Offline
Зарегистрирован: 05.08.2014

Возможны несколько путей. Конкретно в Вашем примере симпатично выглядит передавать вместо data указатель на функцию с действием data[i] = Wire.read(); В ней и будет скрыта специфика передачи типа. Ищите про callback. Это не самый простой путь, но самый перспективный, возможно позволит вобще от массива избавится.

Воще код написан плохо, то что data массив нужного размера с чего видно? Где контролируется? 

DarkDaemon
Offline
Зарегистрирован: 31.10.2015

На гугле не забанен, но ничего толкового по словам arduino callback не нашел. Вот тут вроде сказано:

http://www.gammon.com.au/callbacks

Где бы найти подробное объеснение для нубов на русском языке... :)

В смысле, "массив нужного размера"? Кому нужного? Допустим, data имеет размер 20. Нам надо считать 10 байт, число 10 передается аргументом nRead.

Logik
Offline
Зарегистрирован: 05.08.2014

DarkDaemon пишет:

На гугле не забанен, но ничего толкового по словам arduino callback не нашел. Вот тут вроде сказано:

http://www.gammon.com.au/callbacks

Где бы найти подробное объеснение для нубов на русском языке... :)

оно не специфично ардуиновское, оно общечеловеческое - https://ru.wikipedia.org/wiki/Callback_(%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5)

DarkDaemon пишет:

 

В смысле, "массив нужного размера"? Кому нужного? Допустим, data имеет размер 20. Нам надо считать 10 байт, число 10 передается аргументом nRead.

так в цикле, строки 8-12 не плохо бы индекс контролировать, чтоб за  nRead не вылез никогда, мало ли шо там Wire напринимает. Явный контроль в таких случаях предпочтительней, т.к. стрельба по памяти очень неприятная ошибка

DarkDaemon
Offline
Зарегистрирован: 31.10.2015

Спасибо за статью, все понятно объяснено. Но нет ли более изящного решения?

Например, передать в функцию параметр

const void *a

и параметр с указанием типа (0 - byte, 1 - char)

byte type
А в самой функции уже их интерпретировать в зависимости от параметра type 
 
if (type == 0) byte a1 = *(byte*)a; else char a1 = *(char*)a;

 

По поводу Wire. Мне кажется, он не должен вернуть больше, чем у него запросили через requestFrom.

Wire.requestFrom(ctrlByte, nRead);

 

vk007
Offline
Зарегистрирован: 16.06.2015

Может я не все понимаю, но данные, что byte, что char в памяти хранятся в одинаковом 8-битовом виде. Почему бы не сохранять их всегда как byte, а уже при работе с ними извлекать в том виде, в каком надо.

Datak
Offline
Зарегистрирован: 09.10.2014

DarkDaemon пишет:

Спасибо за статью, все понятно объяснено. Но нет ли более изящного решения?

Например, передать в функцию параметр...

DarkDaemon, передача параметра "вручную " - не самое изящное решение.

Погуглите про шаблоны (template) в C++. Конкретно - про шаблоны функций.

http://cppstudio.com/post/5165/

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

Такой вариант не работает?

void foo(byte *par)
{
  par[0] = 1;
}

byte data_byte[2];
char data_char[2];

void setup() {
  foo(data_byte);
  foo((byte *)data_char);
}

void loop() {
  // put your main code here, to run repeatedly:

}

 

DarkDaemon
Offline
Зарегистрирован: 31.10.2015
foo((byte *)data_char);

Да, работает! То что нужно! Приведение типов - изящнее некуда :) Спасибо.