Деление массива байтов: какой функцией?

junior_developer
Offline
Зарегистрирован: 27.11.2017
То есть  например из 16-ти байтного массива:
byte mainBuffer[] = {
0x00, 0x01, 0x02, 0x03,
0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0A, 0x0B,
0x0C, 0x0D, 0x0E, 0x0F
};
получить такие 4 массива по 4 байта

byte buffer_0[] = {0x00, 0x01, 0x02, 0x03};
byte buffer_1[] = {0x04, 0x05, 0x06, 0x07};
byte buffer_2[] = {0x08, 0x09, 0x0A, 0x0B};
byte buffer_3[] = {0x0C, 0x0D, 0x0E, 0x0F};

Есть ли готовая функция для этого? Подскажите пожалуйста, кто разбирается!

 

vlad072
Offline
Зарегистрирован: 01.08.2017
byte buffer_0[4] = mainBuffer;
byte buffer_1[4] = mainBuffer + 4;
byte buffer_2[4] = mainBuffer + 8;
byte buffer_3[4] = mainBuffer + 12;

Оно?

b707
Онлайн
Зарегистрирован: 26.05.2017

Вариант 1 - очевидный - два вложенных цикла for

Вариант 2 - для эстетов - описать 16 байтовый массив как унион для четырех переменных типа лонг

b707
Онлайн
Зарегистрирован: 26.05.2017

vlad072 пишет:

byte buffer_0[4] = mainBuffer;
byte buffer_1[4] = mainBuffer + 4;
byte buffer_2[4] = mainBuffer + 8;
byte buffer_3[4] = mainBuffer + 12;

Оно?

шикарно

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016
vlad072
Offline
Зарегистрирован: 01.08.2017

Тфу, вот так всмысле

byte* buffer_0 = mainBuffer;
byte* buffer_1 = mainBuffer + 4;
byte* buffer_2 = mainBuffer + 8;
byte* buffer_3 = mainBuffer + 12;

Только это будет не копия а ссылки на элементы, соответственно границы надо контролировать самому.

sadman41
Offline
Зарегистрирован: 19.10.2016

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

junior_developer
Offline
Зарегистрирован: 27.11.2017

b707 пишет:
Вариант 1 - очевидный - два вложенных цикла for

Вы имеете в виду что-то вроде этого
 

  for (int i = 0; i < 4; i++) // количество массивов
 {
?????
     for (int j = 0; j < 4; j++) // количество байт
      {
      ?????
      }
 }

Но названия у массивов ведь разные! Как их запихнуть в цикл for? 

brokly
brokly аватар
Offline
Зарегистрирован: 08.02.2014

Вариант № 1

union uMassConv {
  uint8_t raw[16];
  uint8_t fofo[4][4];
};

uMassConv myMass;

void setup() {
   for(uint8_t i=0;i<16;i++){
      myMass.raw[i]=i+1;
   }
   for(uint8_t i=0;i<4;i++){
      for (uint8_t j=0;i<4;j++){
        Serial.print(myMass.fofo[i][j]);
        Serial.print(' ');
      }
      Serial.println();
   }
}

void loop() {
}

Вариант № 2

uint8_t fofo[4][4];
uint8_t* raw=(uint8_t*)fofo;

void setup() {
   for(uint8_t i=0;i<16;i++){
      raw[i]=i+1;
   }
   for(uint8_t i=0;i<4;i++){
      for (uint8_t j=0;i<4;j++){
        Serial.print(fofo[i][j]);
        Serial.print(' ');
      }
      Serial.println();
   }
}

void loop() {
}

 

sadman41
Offline
Зарегистрирован: 19.10.2016

Думаю, что пока ТС не соблаговолит уточнить - что, по его мнению, означает "получить 4 массива", особого смысла в упражнениях нет. 

brokly
brokly аватар
Offline
Зарегистрирован: 08.02.2014

vlad072 пишет:

Тфу, вот так всмысле

byte* buffer_0 = mainBuffer;
byte* buffer_1 = mainBuffer + 4;
byte* buffer_2 = mainBuffer + 8;
byte* buffer_3 = mainBuffer + 12;

Только это будет не копия а ссылки на элементы, соответственно границы надо контролировать самому.

Кстати, ничто не мешает работать с этими массивами так:

buffer_1[1]=20;

А вот buffer_0 излишен, ибо он mainBuffer и есть :)

junior_developer
Offline
Зарегистрирован: 27.11.2017

sadman41 пишет:
Думаю, что пока ТС не соблаговолит уточнить - что, по его мнению, означает "получить 4 массива", особого смысла в упражнениях нет.
Может я не правильно выразился. К сожалению, в программировании совсем не силен! Возможно правильно сказать,  разделить массив на части по 4 байта, чтобы каждую из них можно было использовать отдельно.

Например, есть функция, которая принимает 4 байта и записывает их в память. И чтобы использовать её с буфером, в который считывается дамп памяти, нужно разделить данные по 4  байта.  Чтобы эту функцию можно было запихнуть в цикл for.
То есть алгоритм вроде бы простой:
-взять первые четыре байта из массива; 
-запихнуть их в функцию для записи;
- взять следующие четыре байта из массива;
-запихнуть их в функцию для записи;
и т.д.

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

Объявление функции покажи, пж - как она принимает 4 байта? Это 4 разных параметра, или четырехбайтовая переменная, или просто - указатель на массив? Если последнее, то с точки зрения С++ нет разницы, что передавать - можешь передать указатель на первый элемент массива, а можешь - на пятый, и ничего делить не надо. Например:

void function(byte* bArray)
{
.....
}

byte b[16] = {0};

function(b);
function(b+4);
function(b+8);

 

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

junior_developer пишет:

sadman41 пишет:
Думаю, что пока ТС не соблаговолит уточнить - что, по его мнению, означает "получить 4 массива", особого смысла в упражнениях нет.
Может я не правильно выразился. К сожалению, в программировании совсем не силен! Возможно правильно сказать,  разделить массив на части по 4 байта, чтобы каждую из них можно было использовать отдельно.

Например, есть функция, которая принимает 4 байта и записывает их в память. И чтобы использовать её с буфером, в который считывается дамп памяти, нужно разделить данные по 4  байта.  Чтобы эту функцию можно было запихнуть в цикл for.
То есть алгоритм вроде бы простой:
-взять первые четыре байта из массива; 
-запихнуть их в функцию для записи;
- взять следующие четыре байта из массива;
-запихнуть их в функцию для записи;
и т.д.

junior_developer, давайте разделять понятия "есть" и "можно написать".

По поводу "есть", длина массива даже для Уно, Нано, Мини может быть от 2 до примерно 2000. Длина каждой из частей тоже может быть примерно от 1 до 2000. Итого, на все случаи жизни требуется около 4 миллионов разных функций (это еще если не учитывать Micro, Due, stm32duino и пр.), как Вы думаете, они уже где-то есть готовые? 

Ну а по поводу "можно написать" - да, можно. Причем, это совсем не сложно.

junior_developer
Offline
Зарегистрирован: 27.11.2017

DIYMan пишет:
Объявление функции покажи, пж - как она принимает 4 байта? Это 4 разных параметра, или четырехбайтовая переменная, или просто - указатель на массив?

​byte *buffer, ///< The 4 bytes to write to the PICC

А вот функция целиком:

MFRC522::StatusCode MFRC522::MIFARE_Ultralight_Write( byte page,  ///< The page (2-15) to write to.
byte *buffer,	///< The 4 bytes to write to the PICC
byte bufferSize	///< Buffer size, must be at least 4 bytes. Exactly 4 bytes are written.
													) {
	MFRC522::StatusCode result;
	
	// Sanity check
	if (buffer == nullptr || bufferSize < 4) {
		return STATUS_INVALID;
	}
	
	// Build commmand buffer
	byte cmdBuffer[6];
	cmdBuffer[0] = PICC_CMD_UL_WRITE;
	cmdBuffer[1] = page;
	memcpy(&cmdBuffer[2], buffer, 4);
	
	// Perform the write
	result = PCD_MIFARE_Transceive(cmdBuffer, 6); // Adds CRC_A and checks that the response is MF_ACK.
	if (result != STATUS_OK) {
		return result;
	}
	return STATUS_OK;
} // End MIFARE_Ultralight_Write()

Она из библиотеки https://github.com/miguelbalboa/rfid

 

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

Ну и зачем делить массив? Пример - я писал - просто скармливаешь функции указатель на нужный элемент массива:

byte b[16] = {0};

mifare.MIFARE_Ultralight_Write(0,b,4);

mifare.MIFARE_Ultralight_Write(0,b+4,4);

mifare.MIFARE_Ultralight_Write(0,b+8,4);

mifare.MIFARE_Ultralight_Write(0,b+12,4);

 

junior_developer
Offline
Зарегистрирован: 27.11.2017

Большое спасибо всем, кто помог!

Для ясности добавлю ещё образец вызова этой функции
 

  for (int i=0; i < 4; i++) {
    //data is writen in blocks of 4 bytes (4 bytes per page)
    status = (MFRC522::StatusCode) mfrc522.MIFARE_Ultralight_Write(pageAddr+i, &buffer[i*4], 4);
    if (status != MFRC522::STATUS_OK) {
      Serial.print(F("MIFARE_Read() failed: "));
      Serial.println(mfrc522.GetStatusCodeName(status));
      return;
    }
  }

В таком варианте она работает правильно! Пишутся 4 страницы по 4 байта! Кстати под буффер выделено не 16 байтов, а 18!
 

byte buffer[18];  //data transfer buffer (16+2 bytes data+CRC)

И код целиком 

/* mifare ultralight example (25-02-2018)
 * 
 *   RFID-RC522 (SPI connexion)
 *   
 *   CARD RC522      Arduino (UNO)
 *     SDA  -----------  10 (Configurable, see SS_PIN constant)
 *     SCK  -----------  13
 *     MOSI -----------  11
 *     MISO -----------  12
 *     IRQ  -----------  
 *     GND  -----------  GND
 *     RST  -----------  9 (onfigurable, see RST_PIN constant)
 *     3.3V ----------- 3.3V
 *     
 */

  #include <SPI.h>
  #include <MFRC522.h>
  
  
  #define SS_PIN          10
  #define RST_PIN         9

  MFRC522 mfrc522(SS_PIN, RST_PIN);  // Create MFRC522 instance
  MFRC522::StatusCode status; //variable to get card status
  
  byte buffer[18];  //data transfer buffer (16+2 bytes data+CRC)
  byte size = sizeof(buffer);

  uint8_t pageAddr = 0x06;  //In this example we will write/read 16 bytes (page 6,7,8 and 9).
                            //Ultraligth mem = 16 pages. 4 bytes per page.  
                            //Pages 0 to 4 are for special functions.           
  
void setup() {
  Serial.begin(9600); // Initialize serial communications with the PC
  SPI.begin(); // Init SPI bus
  mfrc522.PCD_Init(); // Init MFRC522 card  
  Serial.println(F("Sketch has been started!"));
  memcpy(buffer,"HELLO WORLD! ;-)",16);
}

void loop() {
  // Look for new cards
  if ( ! mfrc522.PICC_IsNewCardPresent())
    return;

  // Select one of the cards
  if ( ! mfrc522.PICC_ReadCardSerial())
    return;

  // Write data ***********************************************
  for (int i=0; i < 4; i++) {
    //data is writen in blocks of 4 bytes (4 bytes per page)
    status = (MFRC522::StatusCode) mfrc522.MIFARE_Ultralight_Write(pageAddr+i, &buffer[i*4], 4);
    if (status != MFRC522::STATUS_OK) {
      Serial.print(F("MIFARE_Read() failed: "));
      Serial.println(mfrc522.GetStatusCodeName(status));
      return;
    }
  }
  Serial.println(F("MIFARE_Ultralight_Write() OK "));
  Serial.println();


  // Read data ***************************************************
  Serial.println(F("Reading data ... "));
  //data in 4 block is readed at once.
  status = (MFRC522::StatusCode) mfrc522.MIFARE_Read(pageAddr, buffer, &size);
  if (status != MFRC522::STATUS_OK) {
    Serial.print(F("MIFARE_Read() failed: "));
    Serial.println(mfrc522.GetStatusCodeName(status));
    return;
  }

  Serial.print(F("Readed data: "));
  //Dump a byte array to Serial
  for (byte i = 0; i < 16; i++) {
    Serial.write(buffer[i]);
  }
  Serial.println();

  mfrc522.PICC_HaltA();

}

Нашел его в ответе на вопрос в этом топике

Да, в таком виде код рабочий, но если попробовать записывать не 16 байт, а например 64 - не работает!!!
У меня уже возникло предположение, что тут не обойтись без ещё одного цикла for!
То есть, чтобы получить 64, нужно просто запихнуть этот вызов функции в цикл for и повторить его 4 раза, просто меняя значение указателя!
А под буфер тогда нужно выделить 18*4=72 байта! 16*4=64(под данные) 2*4=8 (для контрольных сумм). Правильно ли я рассудаю?

И ещё обратил внимание на такую деталь: в функции записи есть вот такая закорючка "&", а в функции чтения - нет!
То есть вот так:

&buffer 

buffer

Нужна ли она?

brokly
brokly аватар
Offline
Зарегистрирован: 08.02.2014

junior_developer пишет:

И ещё обратил внимание на такую деталь: в функции записи есть вот такая закорючка "&", а в функции чтения - нет!

То есть вот так:

&buffer 

buffer

Нужна ли она?

Вам нужно срочно что нибудь почитать ! Пока вас отсюда ссаными тряпками в песочницу не загнали !

vlad072
Offline
Зарегистрирован: 01.08.2017

brokly пишет:

[buffer_0 излишен, ибо он mainBuffer и есть :)

Согласен. Ну как бы для наглядности примера

brokly
brokly аватар
Offline
Зарегистрирован: 08.02.2014

Ну, а в чем наглядность то ? Вот даже не понимаю, это поток мысли, так сказать, или поток желчи ? Или это смесь "мысли так сказать" с желчью ? Не понимаю как вам отвечать. Но в принципе, если сумеете сформулировать мысль, то я вам обязательно отвечу :)

vlad072
Offline
Зарегистрирован: 01.08.2017

Это мне? Где в моём посте "желчь"??

brokly
brokly аватар
Offline
Зарегистрирован: 08.02.2014

А она там есть ? Я же и спрашиваю, что это ?