bool arr[]={0,1,0,0,0,0,0,0} сконвертировать в byte B01000000
- Войдите на сайт для отправки комментариев
Ср, 14/03/2018 - 20:30
Приветствую. Имею массив, к примеру bool arr[]={0,1,0,0,0,0,0,0}
Мне нужно сконвертировать этот массив в byte следующего формата - B01000000.
Это нужно для использования в библиотеке LedControl: LC.setRow(int address, int row, byte value);
http://www.c-cpp.ru/books/bitovye-operatory и дальше сами.
pahuchiy, конвертировать-то его нетрудно, вот только нафига? Может лучше изнчально не создавать его и не транжирить память. Он же по байту на бит жрёт! Что мешет сразу записать в виде битов? Задача-то какая?
pahuchiy, конвертировать-то его нетрудно, вот только нафига? Может лучше изнчально не создавать его и не транжирить память. Он же по байту на бит жрёт! Что мешет сразу записать в виде битов? Задача-то какая?
Я ж делаю миди-секвенсор))). Так вот хочу записывать ноты в двумерный массив: по вертикали - ноты, по горизонтали время. Мне кажется, удобно. Не?
А зачем их так записывать? В восемь раз память перерасходвать? Сделайте union на байт и массив из восьми битовых полей по одному биту и пишите свои биты прямо в этот байт безо всяких конверсий. Визульно это будет выглядеть также (последовательность нулей и единиц). Если не знаете что такое union и "битовые поля", то ключевые слова для поиска у Вас теперь есть.
Приветствую. Имею массив, к примеру bool arr[]={0,1,0,0,0,0,0,0}
Мне нужно сконвертировать этот массив в byte следующего формата - B01000000.
А нужно ли оно вам, и зачем - это вы думайте сами.
Olej, Вы биты случаем не перевернули? Хотя, никто не знает как ТС нужно LSB или MSB вперёд пихать.
Приветствую. Имею массив, к примеру bool arr[]={0,1,0,0,0,0,0,0}
Мне нужно сконвертировать этот массив в byte следующего формата - B01000000.
А нужно ли оно вам, и зачем - это вы думайте сами.
Как исправить?
после autoit и lua, С++ очень сложен....
void loop() {
sizeof( ... ) - не дописал ;-)
Но можете просто заменить на 8: for( int i = 0; i < 8; i++ ) ...
не горит(
А так горит - lc.setRow(0,1,B01000000); ?
да
Я вам не обещал что будет гореть.
Я обещал преобразовать в byte.
P.S. Ну выведите b в Serial и наблюдайте значение.
Я вам не обещал что будет гореть.
Я обещал преобразовать в byte.
P.S. Ну выведите b в Serial и наблюдайте значение.
выводит 0
P.S. Ну выведите b в Serial и наблюдайте значение.
выводит 0
Ну, может с приоритетами операций там что-то не так ... поэкспериментируйте со скобками, например так:
Расстановка скобок для управления приоритетами должно быть обычной практикой.
Но, в конечном итоге, должно быть как-то так... Вы должны видеть значение b по Serial - 64 (для вашего примера). После того, как добьётесь отладкой результата, лишние скобки можете убрать.
P.S. Ну выведите b в Serial и наблюдайте значение.
выводит 0
Ну, может с приоритетами операций там что-то не так ... поэкспериментируйте со скобками, например так:
Расстановка скобок для управления приоритетами должно быть обычной практикой.
Но, в конечном итоге, должно быть как-то так... Вы должны видеть значение b по Serial - 64 (для вашего примера). После того, как добьётесь отладкой результата, лишние скобки можете убрать.
спасибо, горит!
Я ж делаю миди-секвенсор))). Так вот хочу записывать ноты в двумерный массив: по вертикали - ноты, по горизонтали время. Мне кажется, удобно. Не?
А какая предполагаемая длина последовательности секвенора?
Для 4 тактов 4/4 получается: (4 такта) * (96 MIDI Clock) * (97 нот) * (1 байт) = 37248 байта, т.е. более 32 KiB. Даже для Arduino Due весьма существенная величина, а для MEGA 2560 - и вовсе неподъемная.
Но можете просто заменить на 8: for( int i = 0; i < 8; i++ ) ...
Я ж делаю миди-секвенсор))). Так вот хочу записывать ноты в двумерный массив: по вертикали - ноты, по горизонтали время. Мне кажется, удобно. Не?
А какая предполагаемая длина последовательности секвенора?
Для 4 тактов 4/4 получается: (4 такта) * (96 MIDI Clock) * (97 нот) * (1 байт) = 37248 байта, т.е. более 32 KiB. Даже для Arduino Due весьма существенная величина, а для MEGA 2560 - и вовсе неподъемная.
спасибо, да, уже пересмотрел способ хранения данных. Буду записывать только существующие ноты, а всё остальное по умолчанию будет false
Странный Вы человек, я Вам рассказал как хранить в восемь раз компактнее, но Вы упорно цепляетесь за то, чтобы хранить именно так, как никуда не влазит и мастырить костыли.
Ему надо увидеть это.
Странный Вы человек, я Вам рассказал как хранить в восемь раз компактнее, но Вы упорно цепляетесь за то, чтобы хранить именно так, как никуда не влазит и мастырить костыли.
Я вам крайне благодарен за совет. Я скорее всего так или подобным образом и сделаю в будущем. Но на данном этапе моих навыков в C++ не достаточно чтобы реализовать это (собственно, я около недели назад начал разбираться в C++). То что я делаю сейчас - это промежуточный вариант. Для тренеровки, так сказать.
Ему надо увидеть это.
спасибо
Ну тогда еще чуть чуть добавлю ;) Обратите внимание, при таком подходе вам вручную ничего конвертировать не придется .
Смысл такой.
Сначала вы описали битовую структуру размером с байт, где каждому биту соответствует сове поле.
Потом описали объединение, обращаясь к полям которого вы к одному и тому же содержимому можете обратиться как к байту или как к биту.
простите за офф
а это только массив так жрёт? bool arr[]= {0,0,0,0,0,0,0,0}
или просто переменная bool тоже 1 байт в памяти занимает? мне так, для общего развития
А я наивный думал что 1 бит))
или просто переменная bool тоже 1 байт в памяти занимает?
Конечно. Ничего не занимает меньше, чем байт. Хотя бы уже потому, что байт - минимальная адресуемая единица.
Если вместо поля bitfield поставить безымянное поле, то запись получается компактнее
Откуда инфа? Где менять ключи оптимизации компилятора? Потому что если реальный факт, то у авторов компилятора реально мозг птички, такие вещи должны сжиматься автоматически. Не?
Откуда инфа? Где менять ключи оптимизации компилятора? Потому что если реальный факт, то у авторов компилятора реально мозг птички, такие вещи должны сжиматься автоматически. Не?
О_О sizeof(boolean) == 1 байт, а не 1/8-я байта
у компиллятора нет мозга - мозг птички у программиста
Откуда инфа?
Инфа из понимания программирования и знания языка.
Запомните, ни одна самостоятельная сущность (переменная, экземпляр класса, любая сущность) не может занимать в памяти меньше одного байта и не может занимать нецелое количество байтов.
(Чтобы сразу закрыть вопрос о битовых полях - битовое поле не является самостоятельной сущностью - оно существует только в составе группы полей. Самостоятельной сущностью является группа полей, а не отдельное поле. Причём любая группа битовых полей, хоть состоящая из одного поля - всё равно занимает целый байт (или целое количество байтов))
Где менять ключи оптимизации компилятора?
Никакие ключи не помогут - это вытекает из очень глубокой сущности языка. Дело в том, что любая сущность в программе обязана иметь адрес, а байт - минимальная адресуемая единица. Мы не можем записать адрес объекта, занимающего только часть байта (вернее, объекта, начинающегося не с границы байта). Потому таких объектов в языке нет и быть не может.
Более того, представим себе класс в котором вообще нет ни одного свойства - ну ни одного и, стало быть, память занимать просто нечему. Вот, например:
Сколько по Вашему места занимает переменная kaka? Можете проверить - один байт. Нафига ей нужен этот байт? Чего в нём хранить? А ничего - просто она обязана иметь адрес, а пустота адреса не имеет. Отдельно взятый бит адреса тоже не имеет. Адрес может быть только у байта или группы байтов.
такие вещи должны сжиматься автоматически. Не?
Теперь понятно, спасибо! Это типа как кластер на жестком диске или флешке. Минимальная единица хранения информации. Меньше его не могут объекты занимать.
Евгений, думаю, что еще стоит добавить про округление структур и юнионов в памяти кратно байту. То есть структура из одного бита, все равно займет байт. Ну это в наших 8 битных ардуинах.
Откуда инфа? Где менять ключи оптимизации компилятора? Потому что если реальный факт, то у авторов компилятора реально мозг птички, такие вещи должны сжиматься автоматически. Не?
Тут кстати не авторы компилятора виноваты, а стандарт.
Никакие ключи не помогут - это вытекает из очень глубокой сущности языка. Дело в том, что любая сущность в программе обязана иметь адрес, а байт - минимальная адресуемая единица.
Ну да.
Только язык здесь ни при чем.
Теперь понятно, спасибо! Это типа как кластер на жестком диске или флешке. Минимальная единица хранения информации. Меньше его не могут объекты занимать.
Нет, выше была правильная формулировка: минимальный адресуемый объем информации.
Только язык здесь ни при чем.
Да, ладно! А что же здесь причём?
Вся байда вылезла из жёсткого требования языка, чтобы унарная операция "&" была применима к любому lvalue и любому qualified-id, кроме битовых полей. (ISO IEC 14882 - 2014 стр. 108, п. 5.3.1 (3-6))
Существует огромное множество языков в которых нет операции взятия адреса, и в них такой проблемы нет от слова совсем. Там разработчики компилятора могут запросто засунуть 8 bool переменных в один байт и не париться, что часто и делается.
а почему, если
написать не в лупе, то: 'x' does not name a type ?
Ведь, как я понимаю, - это инициализация юниона x. Да? Зачем его в лупе зацикливать?
а почему, если
написать не в лупе, то: 'x' does not name a type ?
Вы тут вроде довольно давно, но так и не поняли, что без кода вопросы задавать нельзя. Хрустальные шары на этом форуме запрещены, а потому мне просо неоткуда знать где Вы это написали, как написали. У меня работает нормально, где бы я не писал. Нужет отет - давайте код.
Ведь, как я понимаю, - это инициализация юниона x. Да? Зачем его в лупе зацикливать?
Вы что нибудь про видимость переменных читали ?
В начале цикла содается переменная, доступная только в этом цикле. Вы ее используете один раз, во время прохода цикла. По окончании прохода цикла она разрушается. Мне она за пределами цикла была не нужна, поэтому я и объявил ее в начале цикла. Это и есть ответ на ваш вопрос.
Ведь, как я понимаю, - это инициализация юниона x. Да? Зачем его в лупе зацикливать?
Вы что нибудь про видимость переменных читали ?
В начале цикла содается переменная, доступная только в этом цикле. Вы ее используете один раз, во время прохода цикла. По окончании прохода цикла она разрушается. Мне она за пределами цикла была не нужна, поэтому я и объявил ее в начале цикла. Это и есть ответ на ваш вопрос.
читал про видимость. И знаю что если обьявить переменную как глобальную (а именно так я её и объявляю вне цикла, верно?), то она видна должна быть везде. Так почему ошибка возникает?
На глобальном уровне можно объявлять переменные, но нельзя выполнять действия.
Сделайте одно и двух:
1. Удаляйте строку 26, а в строку 25 добавляйте инициализацию (так луше)
или 2. Перенесите строку 26 внутрь функции setup
И, это, ну что-нибудь про язык-то почитайте.
А какая предполагаемая длина последовательности секвенора?
Для 4 тактов 4/4 получается: (4 такта) * (96 MIDI Clock) * (97 нот) * (1 байт) = 37248 байта, т.е. более 32 KiB. Даже для Arduino Due весьма существенная величина, а для MEGA 2560 - и вовсе неподъемная.
Если я сделаю хранение мидисобытий таким образом (образно): {номер канала, номер строки (нота), номер столбца (время), длительность, велосити}, то чтобы прочитать их для отображения светодиодами и при этом не перебирать в цикле все миди-события, я должен каждую новую ноту (которую добавляю путём нажатия кнопки) ставить в правильном порядке. То есть, к примеру, если у меня уже есть 3 ноты: 1 - на 1-й секунде, 2- на 2-й секунде, 3-на 3-й секунде, то при добавлении новой ноты на 2,5 секунде, я должен поместить её 3-й в очереди сместив при этом одну ноту. В итоге запись произведения будет иметь такой порядок(время): 1 2 2,5 3
И если к примеру у меня в светодиодной матрице только 3 столбца, чтобы отобразить музыку, программа пройдёт все 4 значения, но увидив что 4-е значение выходит за "рамки видимости" светодиодной матрицы, остановится. И если бы дальше шли ещё какие-то ноты, то время на их чтение не тратилось бы. Я верно мыслю?
1. У Вас еще и номер канала есть? В своем подсчете объема информации я исходил из того, что канал единственный. Кстати, как Вы собираетесь управлять номером канала?
2. В протоколе MIDI длительности как таковой не существует. Конечно, для секвенсора ее можно ввести, но есть ряд соображений, по которым целесообразнее использовать пару сообщений Note On и Note Off вместо одного с указанием длительности.
3. Для того, чтобы вставить некоторый объект (например, ноту) в правильное место в последовательности, придумана такая структура данных как список.
Последнего абзаца я не понял.
1. Конечно. На то он и секвенсор. Разве нет? Управление каналом: Младшая половина статус-байта https://habrahabr.ru/post/271693/
2. Да, на момент написания поста я ещё не углублялся в информацию по приведённой выше ссылке. Но теперь я в курсе как правильно.
3. Спасибо
Сейчас переформулирую последний абзац.
Суть в том чтобы обрабатывать (зажигать светодиоды) только те миди события которые укладываются в формат светодиодной матрицы. И работать со следющими только тогда когда настанет их черёд воспроизведения. Ну, впрочем, это и так очевидно. Не стоило, наверное об этом вообще писать.
Видимо, я не представляю себе Ваш проект.
В функции панели входит ввод данных? Если "да", то, думаю, все они должны как-то отображаться.
Т.е. не может быть данных, которые не попадают "в формат". Или нет?
Да, под "как управлять" я подразумевал не внутреннее хранение, а индикацию/ввод данных с панели.
Да, под "как управлять" я подразумевал не внутреннее хранение, а индикацию/ввод данных с панели.
96*24 - это лишь поле ввода нот. Будут и другие органы управления. Смена каналов будет осуществляться с помощью них. Вот примерная схема http://prntscr.com/itgwgy
Не все данные (ноты) будут помещаться на панеле. Будет прокрутка. Её прототип я даже набросал (сори за много мусора в коде):
Круто!
Я тоже люблю большие панели http://arduino.ru/forum/proekty/analog-analogovogo-sintezatora#comment-249334
А энкодеры я бы посоветовал делать на прерываниях. Если энкодеров много - на PCINT.
ну да, крутилки - это наше всё))).
Приятно видеть в среде рускоговорящих ардуинщиков интересующихся музыкой.
Пока что запланирован 1 энкодер и 3 фейдера. Я всегда больше интересовался "живой" музыкой. Поэтому, и девайс горожу под VSTi (рояль, саксофон, живые ударные итд). Ко мне Due едет. А сейчас на Uno и Nano не хочу заморачиваться с прошивками и прочими танцами чтобы как миди-контроллер стали видны в компе.
а насчёт прерываний - спасибо учту на будущее (пока что очень поверхностно понимаю о чём речь, погуглю как руки дойдут)
На мой взгляд, правильный MIDI должен выглядеть так:
Due - да, сейчас с ним отлаживаюсь. Из явных минусов: что-то там намудрили с разводкой земли/питания - никак не могу избавиться от помех, генеримых внешними устройствами, в частности - дисплеем.
С этим делом, вроде, намного лучше в https://ru.aliexpress.com/item/Due-Core-SAM3X8E-32-bit-ARM-Cortex-M3-Mini-Module-Compatible-UC-2102-512K-Flash-96K/32681732855.html
Но что-то там существенно хуже с процедурой прошивки. Впрочем, если отлаживаться на обычной Due, то это без разницы.
Ну и я как-то не понял, как согласуется живая музыка с визуальным секвенсором.
да, терминологически, она не живая. Но, скажем так, живее прочей электронщины. И, если получится, я по максимуму сделаю возможным редактирование тонких настроек звукоизвлечения (скорость нажатия, послекасание, итд). А раньше я плотно занимался именно живой музыкой (запись с микрофона живых инструментов) Но это большой труд В плане вложения психо-эмоциональной энергии. Переосмыслив всё это дело, я задался вопросом: а надо ли мне это? И понял что нет. А вот шаговый железный секвенсор - это проще. Это можно сравнить со стратегией и шутером от первого лица. (живая музыка - шутер, шаговый секвенсор - стратегия) Ну и, есть вероятность продать девайс если удачным получится.