В ардуино нет бинарных типов данных?

Тема в разделе "Флудилка", создана пользователем r13s, 11 авг 2015.

  1. r13s

    r13s Нерд

    Хотел я записать в постоянную память ардуино массив в 1024 бита, таким образом у меня бы получилось занять небольшую часть памяти, а если я буду записывать байт, то как раз весь килобайт забьется на UNO. или я что то не так думаю? значение я хочу хранить правда или лож
     
  2. Unixon

    Unixon Оракул Модератор

    Как-то так...

    Код (Text):

    byte data[128]; // 1024/8

    bool readBit(int index)
    {
      int byte_index = index>>3;
      byte bits = data[byte_index];
      int bit_index = index & 0x7; // same as (index - byte_index<<3) or (index%8)
      byte mask = 1<<bit_index;
      return (0!=(bits & mask));
    }

    void writeBit(int index, bool value)
    {
      int byte_index = index>>3;
      byte bits = data[byte_index];
      int bit_index = index & 0x7; // same as (index - byte_index<<3) or (index%8)
      byte mask = 1<<bit_index;
      byte new_bits = (bits & ~mask) | value<<bit_index;
      data[byte_index] = new_bits;
    }
     
     
    Последнее редактирование: 12 авг 2015
    acos, nailxx, Tomasina и ещё 1-му нравится это.
  3. r13s

    r13s Нерд

    спасибо попробуем
     
  4. Megakoteyka

    Megakoteyka Оракул Модератор

    Компилятор догадается переделать это в index & 0x07 ?
     
  5. ИгорьК

    ИгорьК Гуру

    Такие примочки надо где-то на отдельной доске вешать. Потом ведь не вспомнишь где видел...
     
  6. Unixon

    Unixon Оракул Модератор

    Ну, да, это я неоптимально записал. :)

    Конечно, нужно bit_index = index & 0x07;
     
  7. Unixon

    Unixon Оракул Модератор

    Эти примочки должны автоматически генерироваться мозгом на лету.
     
  8. Megakoteyka

    Megakoteyka Оракул Модератор

    Маска накладывается быстро, а с делением как дела обстоят?
    Я в таких ситуациях рассуждаю так:
    - нужно обращаться к битам по сквозному номеру, биты хранятся в байтах.
    - тогда номер бита в байте будет 0..7 - стало быть, нужно 3 разряда
    - тогда остальные разряды будут номером байта
    - тогда byteIndex = index >>3; и bitIndex = index & 0x07;
    Даже в голову не приходило, что тут еще и делить можно :)
     
  9. Megakoteyka

    Megakoteyka Оракул Модератор

    Если все полезняшки вешать на стенку, то можно хорошо сэкономить на обоях :)
    Я раньше в блокнотик записывал всякие нужные вещи и почти ни разу им не воспользовался в итоге - когда оно нужно, оно само из головы выскакивает.
     
  10. Unixon

    Unixon Оракул Модератор

    Да я просто не сразу сообразил, о чем речь.
     
  11. Alex19

    Alex19 Гуру

    Есть еще битовые поля в СИ.

    Простой пример.
    Код (Text):

    struct status_type {
      unsigned delta_cts: 1;
      unsigned delta_dsr: 1;
      unsigned tr_edge:  1;
      unsigned delta_rec: 1;
      unsigned cts:      1;
      unsigned dsr:      1;
      unsigned ring:      2;
    } status_modem;

    void setup()
    {
      Serial.begin(9600);

      Serial.print("Size of - ");
      Serial.println(sizeof(status_modem));
    }

    void loop()
    {
      Serial.print("Begin - ");
      Serial.println(status_modem.ring, BIN);
      status_modem.ring = 1;

      Serial.print("Set 1 BIN - ");
      Serial.println(status_modem.ring, BIN);
      Serial.print("Set 1 DEC - ");
      Serial.println(status_modem.ring);

      status_modem.ring = 3;
      Serial.print("Set 3 BIN - ");
      Serial.println(status_modem.ring, BIN);
      Serial.print("Set 3 DEC - ");
      Serial.println(status_modem.ring);

      delay(1000);
    }
    Подробнее, тут - http://lord-n.narod.ru/download/books/walla/programming/Spr_po_C/07/0707.htm.

    Производительность не сравнивал, но предположу, что прямая работа с битами предложенная
    Unixon будет быстрее.

    Но порой приходится идти на компромисс и выбирать не самое быстрое решение, а к примеру более удобное для дальнейшей поддержки. Тем более
     
    acos и nailxx нравится это.
  12. Unixon

    Unixon Оракул Модератор

    А тут дело не в скорости, просто битовые поля AFAIK не индексируются. Ну по потом, ТС хотел массив битов - ТС получил массив битов. :)
     
  13. Alex19

    Alex19 Гуру

    Там много минусов.
    Но знания лишними не будут:).
     
  14. Megakoteyka

    Megakoteyka Оракул Модератор

    Не во всяком СИ есть битовые поля, к сожалению. (знания лишними не будут)
     
  15. Alex19

    Alex19 Гуру

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

    Речь идет о стандартах Си к примеру C99?

    UPD. Покопался в форматах, нет дело не в них (не нашел упоминаний, что был добавлен в какой-то стандарт). Возможно в конкретных компиляторах, которые не соответствую стандартам (к компилятору Arduino не относится, он понимает битовые поля).
     
    Последнее редактирование: 12 авг 2015
  16. Megakoteyka

    Megakoteyka Оракул Модератор

    Скорее о конкретных реализациях стандарта. Я как раз с таким компилятором С работаю, который не знает про битовые поля.
     
    Alex19 нравится это.
  17. r13s

    r13s Нерд

    я тут порылся и нашел вот это
    но не смог найти примеров, попытался сам записать байт битов и считать его, но тщетно выдает не логичные результаты.
    не могу в частности разобраться с описанием переменных в операторе.
    bitRead(x, n)

    Параметры
    х: номер, с которого читать
    n: какой бит для чтения, начиная с 0 для наименее значимым (крайний справа) бита
    Возвращает
    Значение бита (0 или 1).

    а bitWrite() там аж 3 параметра
    Я немного ошибся в Т.З. оказывается мне нужно записать не 1024 бита, а 8192 бита, что соответствует 1 кб.
    каждый бит соответствует пикселю на дисплее его количество пикселей 128 х 64 = 8192.
     
  18. DrProg

    DrProg Вечный нерд

    Эти операторы работают с битами в пределах байта. Для килобайта в первом ответе написали функции, чем не нравятся?
     
    ИгорьК нравится это.
  19. r13s

    r13s Нерд

    не смог разобраться, компилятор ошибку выдает
     
  20. r13s

    r13s Нерд

    Unixon, подскажите почему то не идет заполнение битами, сперва я проверяю ячейки, забиваю а они по прежнему нули.
    Код (Text):
    #include <stdio.h>
    #include <EEPROM.h>
    #include <Adafruit_ssd1306syp.h>
    #define SDA_PIN 13
    #define SCL_PIN 12
    #define MINUS_PIN 11
    #define PLUS_PIN 10
    Adafruit_ssd1306syp display(SDA_PIN, SCL_PIN);
    int i,x,y;
    void setup() {
      // put your setup code here, to run once:
     
      pinMode(11, OUTPUT);
      pinMode(10, OUTPUT);
      digitalWrite(MINUS_PIN, LOW);
      digitalWrite(PLUS_PIN, HIGH);
      delay(1000);
      display.initialize();

    Serial.begin(9600);


    }
    byte data[1024]; // 1024/8

    bool readBit(int index)
    {
      int byte_index = index>>3;
      byte bits = data[byte_index];
      int bit_index = index & 0x7; // same as (index - byte_index<<3) or (index%8)
      byte mask = 1<<bit_index;
      return (0!=(bits & mask));
    }

    void writeBit(int index, bool value)
    {
      int byte_index = index>>3;
      byte bits = data[byte_index];
      int bit_index = index & 0x7; // same as (index - byte_index<<3) or (index%8)
      byte mask = 1<<bit_index;
      byte new_bits = (bits & ~mask) | value<<bit_index;
      data[byte_index] = new_bits;
    }
    void loop() {

    for (i=0;i<EEPROM.length();i++) {x=EEPROM.read(i);Serial.print(i);Serial.println(x);}
    Serial.println(""); delay(5000);
    for (i=0;i<EEPROM.length();i++) writeBit(i,0);
    }