Чтение одномерного массива байт как набор разных переменных

Надеюсь, Вы ничего не перепутали и ожидали увидеть в результате именно

вот это
#define printVar16(x) do { Serial.print(#x "=0x"); Serial.print(x, 16); Serial.print("; "); } while (false)
#define printVar16Ln(x) do { Serial.print(#x "=0x"); Serial.println(x, 16); } while (false)

union UVal {
	uint8_t		b[4];
	uint16_t	w[2];
	uint32_t	d;
};

void setup(void) {
	UVal a;
	a.d = 0x11223344;

	Serial.begin(9600);
	printVar16(a.b[0]);
	printVar16(a.b[1]);
	printVar16(a.b[2]);
	printVar16Ln(a.b[3]);
	printVar16(a.w[0]);
	printVar16Ln(a.w[1]);
	printVar16Ln(a.d);
}
void loop(void) {}

// РЕЗУЛЬТАТ
//
// a.b[0]=0x44; a.b[1]=0x33; a.b[2]=0x22; a.b[3]=0x11
// a.w[0]=0x3344; a.w[1]=0x1122
// a.d=0x11223344
//

А вообще, при увлечении эффективностью, будьте осторожны. Штука хорошая, но, помните, она очень опасна. По мнению Уильяма Вульфа, даже опаснее глупости:

Вот, кстати, тоже вариант. Как раз с битовыми полями недавно тренировался, но как -то сразу не подумал. Довольно удобно получается.

Спойлер
union inData {

  struct Byte {
    uint8_t a : 8;
    uint8_t b : 8;
    uint8_t c : 8;
    uint8_t d : 8;
    uint8_t e : 8;
    uint8_t f : 8;
    uint8_t g : 8;
    uint8_t h : 8;
  } inByte;


  struct bitfild1 {
    uint8_t a : 8;
    uint16_t b : 16;
    uint16_t c : 16;
    uint8_t d : 8;
    uint16_t e : 16;
  } fild1;

} indt;


void setup() {
  Serial.begin(115200);
  indt.inByte.a = 0x01;
  indt.inByte.b = 0x01;
  indt.inByte.c = 0x01;
  indt.inByte.d = 0x01;
  indt.inByte.e = 0x01;
  indt.inByte.f = 0x01;
  indt.inByte.g = 0x01;
  indt.inByte.h = 0x01;

  Serial.print(indt.fild1.a, HEX);
  Serial.print(" ");
  Serial.print(indt.fild1.b, HEX);
  Serial.print(" ");
  Serial.print(indt.fild1.c, HEX);
  Serial.print(" ");
  Serial.print(indt.fild1.d, HEX);
  Serial.print(" ");
  Serial.print(indt.fild1.e, HEX);
  Serial.println();

  union inData * p = &indt;//проверяем каждый байт

  uint8_t * pb = (uint8_t*)p;

  for (uint8_t i = 0; i < sizeof(p -> fild1); i++)
  {
    Serial.print(*(pb + i), HEX) ;
    Serial.print(" ");
  }
}

void loop() {

}
Спойлер

Screenshot443 - копия

Да я так и предполагал.

Но в итоге сделал просто битовым сдвигом. Все же так более просто мне показалось.

+1

я еще подумал: а как я это буду разбирать спустя длительное время… ? Все ли мне сходу будет понятно? :slight_smile:

Видите ли, практика показывает, что не менее 85% кода не нуждается в оптимизации. Почему Вы решили, что то, что Вы собираетесь оптимизировать относится к оставшимся 15%?

Не вижу среди этих задач ни одной критичной к скорости процессора.

С какой частотой порисходят прерывания step?

Что значит “минимизировать”?

Вы не приводите ни единой цифры. Вы понимаете, что без конкретных цифр Ваши высказывания полностью бессмысленны?

Вероятно из-за отсутствия достаточного опыта.

Для балансировки и движениия используется 2 ПИД регулятора. Из чтения похожих проектов понял, что период расчетов желательно не реже 5-8 мс.

Однако первое, что меня притормозило - чтение гироскопа. В итоге время цикла расчета (с чтением) стабилизировалось где-то на 8 мс. Датчик bno-55 подключен по i2c шине. Собственно сам датчик рассчитывает углы наклона но делает он это не очень быстро.

Затем полученное значение угла прогонял через 2 ПИД регулятора и получал требуемую скорость на моторы step/dir.

Предполагалась максимальная скорость вращения колес (из расчета линейной скорости 1,5 - 2,5 м/сек) - 13 оборотов колеса в сек.

200 * 16 * 13 * 2 = 83200 кГц на 1 мотор. step формировал таймером по прерыванию. 1 импульс - 2 прерывания 0/1

Соответственно на 2 мотора 160кГц

Помимо этого использовали простенькие сервомоторы, которые при помощи собственной библиотеки плавно меняли скважность ШИМ. Вызов с частотой 50 Гц. 4 сервомотора.

Сейчас приехали сервомоторы управляемые по uart и Nema17 со встроенными энкодерами и драйверами.

Фактически часть нагрузки с esp32 перенесли на драйвера самих моторов.

видимо Герц

Да, опечатка.

Хотел написать 83 кГц но написал в Гц

CAN - это битовая шина. И даже, если бы она была байтовой -это не имеет значения. Big/little endianess проблемы вылазят там, где вы отправляете uin16_t, uin32_t и uint64_t.

Ничего не нужно делать, короче.

ESP32 такой же, как и Intel 86_64 - Little Endian CPU. Это означает, что в памяти числа лежат задом наперед (ну или передом назад - с какой стороны посмотреть): если у вас есть число 0x12345678 то в памяти оно будет лежать как: 78, 56, 34, 12.

Вообще, если не оговорено иного, телекоммуникационные протоколы используют Big Endian формат: первым идет старший байт, затем младший. Но повторюсь - это становится важным лишь тогда, когда у вас передается числа, длинной больше одного байта.

сдвигать и передавать по одному байту )))

Спасибо за разъяснения.

Данные я получил и расшифровал.

И , такой же, как UNO/NANO (5коп.)

Дело же не в коп, а в поддерживаемом формате. На это ударение. А не на какой то там Мотороле с big-endian, которая тоже может быть коп.

Спойлер

Эх.. Какая-то там древняя моторола mpc866 (реально древняя) уделывает современные MCU >:slight_smile:

Второй раз набираю сообщение…

Вчера собрали все модули в 1 проекте.

Загрузили на контроллер.

Не взлетело.

И так напомню.

Балансирующий робот на шаговых моторах с обратной связью с управленинм по can шине.

В качестве гороскопа bno055 на i2c шине.

На i2c еще висит лазерный дальномер но его код сейчас отключен.

Время цикла расчета 8 мс.

За это время получаем значение кгла склонения от гироскопа , рассчитываем 2 пид регулятора (первый вычисляет угол наклона, второй полдердивает угол устанавливая скорость на моторы.

Пил регулятор угла отключен. Пид регулятор урравляющий скоростью моторов оставил только пропорциональную составляющую. Интегральныый и дифференциальные коэф равгы 0.

Держу робота в руках и медленно наклоняю вперед и назад. Скорость колес меняется. Крутятся как положено в сторону склонения.

Показания горисеопа довольно стабильные. Всплесков нет.

Ставлю на колеса и понеслось. То угол 5 градусов, через мгновение -8. Естестаенно моторы с ума сходят.

Вопрос’

С какой частотой допустимо опрашивать датчик bno055?

С какой частотой можно отправлять сообщения на can шину\?

Как часто можно мннять скорость на моторе который уже вращаетсЯ?

Я не стану токсично спрашивать про твое образование, но советую начать все-таки с модели. Попробуй написать модель с одним направлением для начала - только вперед и назад. И отработай на модели допустимые задержки и погрешности. Можешь постепенно физику модели усложнять. Начни просто вертикального стержня бесконечно тонкого с ЦТ посередине и приложением силы к нижнему концу (то есть пока без колеса, для простоты). Пусть сила квантуется как-то, у гироскопа и акселерометра есть погрешности и есть задержки от получения данных, и в исполнительном механизме… И выводящая из равновесия сила пусть “случайный ветер” прикладывается к верхнему концу стержня…
Весьма простые дифуры для такой модельки: три силы - тяжесть к ЦТ, ветер к верхнему концу и управление к нижнему. Распределение плотности по длине пусть самое простое - линейное, или вообще две точечные массы - на концах. Школьник модель напишет, если в состоянии ЕГЭ сдать.

Построй модельку, визуализацию к ней напиши и узнаешь реально ОЧЕНЬ МНОГО НОВОГО! :wink:

ЗЫ: Если не умеешь в “вайб кодинг”, то попроси Бабоса, он немного странный, но этот подход освоил уже ;). По крайней мере модель даст тебе ответ на то, какие задержки и погрешности еще допустимы для управления

В руках на колеса нагрузки нет (сопротивления). В модель нужно заложить сопротивление (инерцию), то есть разгоняемую (затормаживаемую) массу.

Прошу прощения за дублируюшимеся сообщения в темах. Писал с телефона в машине. Один раз сообщение полностью пропало (вместе со связью). Второй раз сам не понял . Но сейчас нашел :slight_smile: Оно в другой ветке.

До ЕГЭ нам еще 3 года. А робота хочется сделать. Теорию изучали на разных примерах. За основу взяли двойной ПИД регулятор.

Предлагаю продолжить в соседней теме. Там как раз сейчас вопрос по CAN/i2c/задержкам …

Кроме прочего, я преподаю математику старшеклассникам, не в РФ, но это не имеет значения.
Я мягко повторю - напиши модель и посмотри на нее на компьютере. Это не трудно.
просто хочу сэкономить твое время и помочь избежать разочарования.

Странный, что б не сказать большего.") Молодёжь. Что с неё взять.(

:rofl:
Я человек воспитанный и слово 2.72банутый не употребляю! :smiling_face_with_sunglasses: