SPI

Тема в разделе "Arduino & Shields", создана пользователем Егор, 6 фев 2014.

  1. Егор

    Егор Нерд

    Простите за глупый вопрос. Такая схема: по SPI подключен выходной сдвиговой регистр, к нему подключено восемь светодиодов. В SPI.transfer() я могу прописать число от 0 до 255, и на выходе он зажжет диоды, в соответствии с двоичным представлением этого числа. А вот теперь собственно вопрос. Я хочу управлять программно каждым диодом. Что то вроде diod1=true; diod2=false; и т.д. И чтобы светодиоды включались и выключались соответственно. Как сконвертировать эти 8 булевских переменных в одну цифру, чтобы послать ее по SPI и все зажглось как надо? Гугление не помогло. Зарание спасибо за ответ.
     
  2. rav_75

    rav_75 Гик

    Есть такая мысля...
    Код (Text):
    //объявляем массив лампочек
    boolean diod[];
    //наши лампочки теперь будут diod[0] - diod[7]
    //объявляем переменную, которую будем задвигать в регистр, статус наших лампочек
    int diodSt=0;
    //заполняем массив значениями false (все выключено)
    for( int i=0; i<=7; i++){
        diod[i]=false;
    }
    //далее идет Ваш код, в нем что-то типа diod[2]=true и т.д.
    //наступает момент, когда надо говорить регистру, что включить
    //делаем финт ушами
    for( int i=0; i<=7; i++){
        if(diod[i]){
            diodSt+=(int)pow(2, (float) i);
        }
    }
    //скармливаем регистру переменную diodSt
    //и обнуляем ее
    diodSt=0;
    //или можно переменную diodSt объявлять в цикле loop(), тогда она будет обнуляться автоматически
    //(если, конечно, не планируете какие-то процедуры - функции, где diodSt может пригодиться)
    Как-то так. Возможно я в чем-то ошибаюсь, поправьте.
     
  3. Unixon

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

    :eek: лучше не стоит так думать...

    Код (Text):

    byte led_state = 0;

    void ledOn(const byte number)
    {
     led_state |= (1<<number);
     SPI.transfer(led_state);
    }

    void ledOff(const byte number)
    {
     led_state &= ~(1<<number);
     SPI.transfer(led_state);
    }
     
     
  4. rav_75

    rav_75 Гик

    Unixon, смысл Вашей реплики понятен :D, как, впрочем, и код. Но вопрос ТС был
    что, собственно, и заинтересовало. Не спрашивайте, зачем это надо, я не знаю. Подскажите, плз, в моем случае не зажгется, как надо? Если нет - то почему? Вроде по логике все норм.
    з.ы. я в этом деле не то, что любитель, у меня даже ардуино нет :D, люблю просто мозгами немножко пошевелить в посторонней области в свободное время. Для разгрузки, так сказать. Бывает ошибаюсь, но от души :D К критике отношусь конструктивно, так что не стесняйтесь :)
     
  5. NR55RU

    NR55RU Гик

    В каком то смысле Unixon уже подкинул вам ответ.
    Создайте булевый массив.
    Далее цикл скажем на 8 итераций.
    Соответственно берите последовательно значения из булевого массива и если оно TRUE то оператором побитового сдвига и побитовой операцией ИЛИ помещайте единицу нужный разряд "выходящего" числа.
    На выходе у вас 8 битовое число с единицами в тех разрядах где у вас TRUE в битовом массиве.
    То есть все 8 итераций вы производите над одной переменной которая будет постепенно менять значения под действиями побитовых операторов.
     
  6. Megakoteyka

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

    Можно и без массива. Байт - тоже своего рода массив из 8 бит. А как обратиться к отдельному биту, Unixon уже продемонстрировал :)
     
  7. NR55RU

    NR55RU Гик

    Да да и это верно :)
    Но вот ТС зачем то нужно именно "8 переменных в одно число собрать", мотивы не ясны но, просит - дали :)
     
  8. Megakoteyka

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

    Подозреваю, что ТС формулирует вопрос так, как сам видит ситуацию, это нормально.
    Откуда могут взяться 8 булевских переменных? Наверное, каждая их них должна устанавливаться по какому-то событию. Но по тому же самому событию можно сразу устанавливать нужный бит в байте. Тогда 8 булевских переменных и заводить не придется. А если учесть, что булевская переменная всегда представляет собой байт, принимающий значения 0 и 1, то получится экономия 8 байт памяти.
     
  9. Егор

    Егор Нерд

    Всем спасибо за ответы) Пока еще нет полного понимания, но думаю допру) А нужно мне это чтобы индикаторную панельку замутить 4х4 диода через 2 регистра, и чтобы она мне некоторую информацию изображала.
     
  10. Unixon

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

    Поскольку в C++ нет сущности property как, например, в Object Pascal, остается только повесить на таймер обработчик прерывания и по нему собирать из массива bool led_state[8] байт и отправлять его в SPI.

    Либо ввести свой хитрый тип данных и переопределить оператор "=" в его отношении.
     
  11. Megakoteyka

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

    А как же битовые поля?

    Накидал быстренько вот это:
    Код (Text):
    struct BITS {
      byte b1 : 1;
      byte b2 : 1;
      byte b3 : 1;
      byte b4 : 1;
      byte b5 : 1;
      byte b6 : 1;
      byte b7 : 1;
      byte b8 : 1;
    };

    BITS bits;

    void setup()
    {
      bits.b1 = 1;
    }
    void loop(){}
    Оно как минимум успешно компилится.
     
  12. Unixon

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

    Ага, ну только оператор присваивания сам не будет автоматически делать SPI.transfer()... если его не перекрыть :) А можно и перекрыть...
     
  13. Megakoteyka

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

    Можно перекрыть и слать байт при изменении каждого разряда, а можно и собрать сперва все биты и только потом слать - тут уж пускай ТС сам думает, чего ему надо :)
     
  14. geher

    geher Гуру

    А ардуино поймет такое?
    Код (Text):
    union ByteBits {
        struct BITS {
            byte b1 : 1;
            byte b2 : 1;
            byte b3 : 1;
            byte b4 : 1;
            byte b5 : 1;
            byte b6 : 1;
            byte b7 : 1;
            byte b8 : 1;
        } Bits;
      unsigned char Byte;
    } bytebits;
    ...
    bytebits.Bits.b5=1;
    ...
    SPI.transfer(bytebits.Byte);