Шар судьбы на Attiny13

Joiner
Offline
Зарегистрирован: 04.09.2014

Решил затеять этот проект. Источник вдохновения здесь https://habr.com/post/241728/ .

Но в данном проекте не понравилось, что шар знает только 2 ответа, "Да" и "Нет". 

Вот код автора

#define F_CPU 1200000UL  // Частота МК в герцах

#include <avr/io.h>
#include <avr/sleep.h> // здесь описаны режимы сна
#include <util/delay.h>

#define led_Yes 0 // grn
#define led_No 1 // red 
#define rand_gen 3 
#define wait 5000 // тайм аут перехода в спящий режим

void setup() {
  //pinMode(led_Yes, OUTPUT); 
  DDRB |= (1<<led_Yes);
  //pinMode(led_No, OUTPUT); 
  DDRB |= (1<<led_No);
}

void loop() {
  randomSeed(analogRead(rand_gen)); // не псевдо радном
  byte randomValue;
  randomValue = random(0,2); // диапазон генератора случайных чисел от 0 до 1
  if(randomValue > 0){   
    //digitalWrite(led_Yes, HIGH);
    PORTB |= (1<<led_Yes);  
  }
  else{
    //digitalWrite(led_No, HIGH); 
    PORTB |= (1<<led_No);  
  }

  _delay_ms(wait); 
  system_sleep();
}

void system_sleep(){ 
  //digitalWrite(led_No, LOW); 
  PORTB &= ~(1<<led_No);
  //digitalWrite(led_Yes, LOW); 
  PORTB &= ~(1<<led_Yes);

  ADCSRA &= ~(1 << ADEN); // перед сном отключим АЦП
  ACSR |= (1 << ACD); // и компаратор
  // для уменьшения энергопотребления во сне
  set_sleep_mode(SLEEP_MODE_PWR_DOWN); // если спать - то на полную
  while(1) {
    sleep_enable(); // разрешаем сон
    sleep_cpu(); // спать!
  }
}

Так как у тиньки остались еще 2 свободные ноги, то решил добавить еще два ответа, "Скорее Да" и "Скорее нет".

Joiner
Offline
Зарегистрирован: 04.09.2014

Немного переделал скетч автора. Вот что получилось

#define F_CPU 1200000UL  // Частота МК в герцах
#include <avr/io.h>
#include <avr/sleep.h> // здесь описаны режимы сна
#include <util/delay.h>

#define led_Yes PB0 // 
#define led_No PB1 // 
#define led_meyBeYes PB2 //
#define led_meyBeNo PB3 //
#define rand_gen PB4 //Здесь считывается фоновые помехи для рандома
#define wait 1000 // тайм аут перехода в спящий режим

void setup() {
  //pinMode(led_Yes, OUTPUT); 
  DDRB |= (1<<led_Yes);
  //pinMode(led_No, OUTPUT); 
  DDRB |= (1<<led_No);
  //pinMode(led_No, OUTPUT); 
  DDRB |= (1<<led_meyBeYes);
  //pinMode(led_No, OUTPUT); 
  DDRB |= (1<<led_meyBeNo);
}

void loop() {
  randomSeed(analogRead(rand_gen)); // не псевдо радном, а последовательность в зависимости от значения на напряжения помехи на пине
  byte randomValue;
  randomValue = random(0,4); // диапазон генератора случайных чисел от 0 (включительно) до 4 (невключительно), т.е до 3
  
    PORTB |= (1<<randomValue);  // Зажигаем случайный светодиод
 

  _delay_ms(wait); 
  system_sleep();
}

void system_sleep(){ 
  //digitalWrite(led_No, LOW); 
  PORTB &= ~(1<<led_No);
  //digitalWrite(led_Yes, LOW); 
  PORTB &= ~(1<<led_Yes);
   //digitalWrite(led_meyBeYes, LOW); 
  PORTB &= ~(1<<led_meyBeYes);
  //digitalWrite(led_meyBeNo, LOW); 
  PORTB &= ~(1<<led_meyBeNo);
  ADCSRA &= ~(1 << ADEN); // перед сном отключим АЦП
  ACSR |= (1 << ACD); // и компаратор
  // для уменьшения энергопотребления во сне
  set_sleep_mode(SLEEP_MODE_PWR_DOWN); // если спать - то на полную
  while(1) {
    sleep_enable(); // разрешаем сон
    sleep_cpu(); // спать!
  }
}

Проверил, работает......Но, как мне показалось устройство тяготеет к определенным пинам. Если нажимать кнопку с небольшими паузами, то загораются разные светодиоды, и создается ощущение случайности.....НО если сделать большую паузу, то загорается в основном светодиод на пине PB3, и иногда на пине PB2.  PB0 и PB1 практически не загораются. И автор говорил про свой "Шар", что у него из двух светодиодов один загорается гораздо чаще.

Решил переделывать дальше.

Joiner
Offline
Зарегистрирован: 04.09.2014

Решил отказаться от рандома. Решил сделать так - программа быстренько изменяет значение переменной от 0 до 3. По нажатию кнопки счет останавливается и переменная приобретает по настоящему случайное значение, и зажигается по значению переменной соответствующий светодиод.

Вот такой скетч получился

#define F_CPU 1200000UL
#include <avr/io.h>
#include <avr/sleep.h> // здесь описаны режимы сна
#include <util/delay.h>

#define BUTTON PB4 // PCINT4
byte L=0;


void setup() {
  DDRB  = 0b00001111;//Конфигурируем PB0, PB1, PB2, PB3 как выход
  DDRB &= ~(1<<BUTTON); // вход

  while ( (PINB & (1<<BUTTON)) != 0)
  {
      L=L+1;
      if (L > 3) L=0;
  }
    PORTB |= (1<<L);
    _delay_ms (5000);
    PORTB &= ~(1<<L);
     _delay_ms(500); 
    system_sleep();
  }

void loop() {}

void system_sleep(){ 
  //digitalWrite(L, LOW); 
  PORTB &= ~(1<<L);
  
  ADCSRA &= ~(1 << ADEN); // перед сном отключим АЦП
  ACSR |= (1 << ACD); // и компаратор
  // для уменьшения энергопотребления во сне
  set_sleep_mode(SLEEP_MODE_PWR_DOWN); // если спать - то на полную
  while(1) {
    sleep_enable(); // разрешаем сон
    sleep_cpu(); // спать!
  }
}

Программа работает прекрасно, по настоящему случайно.... Но приходится нажимать 2 кнопки, Reset и кнопку на PB4. Может кто-то подскажет, чтобы все работало от одной кнопки?

mykaida
mykaida аватар
Offline
Зарегистрирован: 12.07.2018

Не хватает ответов "Будущее не определено" и "В очередь, с*кины дети" (когда очень часто на кнопку нажимают :)

А, в принципе, генератор случайных чисел надо делать аппаратным. Например на шумящих диодах.

Joiner
Offline
Зарегистрирован: 04.09.2014

Для дополнительных ответов ноги закончились, но...думаю, что если использовать, имеющиеся 4 бита, то можно получать 16 случайных ответов, в том числе и "В очередь, с*ки!!!!".

Joiner
Offline
Зарегистрирован: 04.09.2014

Спасибо всем, кто не ответил. Похоже, разберусь сам. Нашел в интернете статейку, где добрый человек делится своим опытом. Там все написано  http://we.easyelectronics.ru/AVR/avr-power-management-ili-kak-pravilno-spat.html

Joiner
Offline
Зарегистрирован: 04.09.2014

Закончена отладка на макете супер проекта "Шар судьбы". 

Схема в двух словах: к ногам 2,5,6,7 подключены светодиоды с токоограничивающими резисторами. Reset(нога 1) подтянут к питанию резистором, и еще эта нога через конденсатор 0,1 мф соединена с ногой 3, к которой присоединена кнопка. Этот пин подтянут резистором к питанию, и при нажатии кнопки, притягивается к земле, и от этой же кнопки через конденсатор срабатывает Reset, тинька просыпается и крутит цикл, пока нажата кнопка. После того как кнопка отпущена получаем случайный номер бита порта, на котором загорится один из 4-х светодиодов, и будет гореть заданное время. Потом тинька заснет до следующего нажатия.

Проверил. Все работает как надо, зажигает, засыпает... Измерил ток во время сна, не знаю на сколько объективно, мой простенький мультиметр показал 0,02 микроампера.

Вот скетчик


#define F_CPU 1200000UL
#include <avr/io.h>
#include <avr/sleep.h> // здесь описаны режимы сна
#include <util/delay.h>

#define BUTTON PB4 // PCINT4
byte LED=0;


void setup() {
  DDRB  = 0b00001111;//Конфигурируем PB0, PB1, PB2, PB3 как выход
//Далее цикл ожидающий отпускания кнопки (светодиоды лихорадочно переключаются)
  while (!(PINB & (1 << BUTTON)))
  {
      LED=LED+1;
      if (LED > 3) LED=0;
      
//Для поверки пока крутится цикл светики по очереди мерцают
//В рабочем скетче эти 2 строчки убрать
      PORTB |= (1<<LED);
      PORTB &= ~(1<<LED);
  }//После отпускания кнопки вылетаем из цикла со случайным значением LED
    PORTB |= (1<<LED);// Зажигаем случайный светодиод
    _delay_ms (5000);//Он светится ...секунд, кому как нравится
    PORTB &= ~(1<<LED);//Гасим светодиод
     _delay_ms(500); 
    system_sleep();
  }

void loop() {}

void system_sleep(){ 
    
  ADCSRA &= ~(1 << ADEN); // перед сном отключим АЦП
  ACSR |= (1 << ACD); // и компаратор
  // для уменьшения энергопотребления во сне
  set_sleep_mode(SLEEP_MODE_PWR_DOWN); // если спать - то на полную
  while(1) {
    sleep_enable(); // разрешаем сон
    sleep_cpu(); // спать!
  }
}

Так как про сон тиньки пока имею смутные понятия, не понимаю, нужен ли в конце подпрограммы void system_sleep() бесконечный цикл в конце. Разве нельзя просто заснуть?

"Шар судьбы" будет в виде брелка-таблетки размером чуть больше батарейки 2032, при сжатии которой она засветится цветом, который определяет ответ на заданный вопрос.

mykaida
mykaida аватар
Offline
Зарегистрирован: 12.07.2018

Joiner пишет:

"Шар судьбы" будет в виде брелка-таблетки размером чуть больше батарейки 2032, при сжатии которой она засветится цветом, который определяет ответ на заданный вопрос.

Хорошая идея! Тогда можно использовать RGB светодиод, а то и с чипом внутри и не заморачиваться с количеством портов.

Joiner
Offline
Зарегистрирован: 04.09.2014

mykaida пишет:

Хорошая идея! Тогда можно использовать RGB светодиод, а то и с чипом внутри и не заморачиваться с количеством портов.

mykaida, спасибо за поддержку! Но только не надо 256 или 256000 цветов. Нам нужен конкретный ответ на конкретный вопрос :) Может кому-то надо только да и нет, кому-то да, нет, затрудняюсь ответить....а кому-то достаточно одного - ДА, ДА, ДА.... Скетчик очень прост, и позволяет сделать желаемое.

Иногда очень помогает. Сегодня спросил у шара....сильно сомневался....выпить мне сегодня, или нет?

Шар однозначно  -  ДА!

sadman41
Онлайн
Зарегистрирован: 19.10.2016

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

Joiner
Offline
Зарегистрирован: 04.09.2014

sadman41 пишет:

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

Шутка понравилась! :)

Мне показалось, что ты из масквы. Спросил у Шара. Он сказал конкретное НЕТ.

Если он ошибся, сразу выброшу на помойку.

sadman41
Онлайн
Зарегистрирован: 19.10.2016

Не врет. Все видит, змеиный глаз.

mykaida
mykaida аватар
Offline
Зарегистрирован: 12.07.2018

Joiner пишет:

 Но только не надо 256 или 256000 цветов.

Ну 256 цветов не каждый глаз разберет, да и ответы там уже будут таблицей юникода :)

А вот семь цветов + белый вполне распознаваемо, особено если возле светодиода нарисовано с расшифровкой. Но это просто идея развития.

С удачным проектом!

Joiner
Offline
Зарегистрирован: 04.09.2014

Спаял плату своего "Шара судьбы". Кому интересно, можно посмотреть здесь  https://youtu.be/KXt2XuiED8g

b707
Offline
Зарегистрирован: 26.05.2017

Шикарный проект!

Joiner
Offline
Зарегистрирован: 04.09.2014

:) Спасибо...

Joiner
Offline
Зарегистрирован: 04.09.2014

Супер проект "Шар судьбы" продолжается. Сегодня напечатал полушарие. Так как модель для печати довольно сложная, пришлось немного поработать наждачкой. А когда вплавлял ушко, немного паяльником поваредил ободок....но это изнутри, незначительно, снаружи не будет видно. В полушарии как в своем доме удобно разместились батарейка и плата....Все работает.

sadman41
Онлайн
Зарегистрирован: 19.10.2016

А откуда он светит?

Joiner
Offline
Зарегистрирован: 04.09.2014

sadman41 пишет:

А откуда он светит?

По центру платы 4 SMD светодиодика. Во второй половинке шара будет круглое матовое окошко. Вот в него они и будут светить.

sadman41
Онлайн
Зарегистрирован: 19.10.2016

Вон оно как... Полусфера даст нажимать кнопку или там толкатель длинный будет?

Joiner
Offline
Зарегистрирован: 04.09.2014

sadman41 пишет:

Вон оно как... Полусфера даст нажимать кнопку или там толкатель длинный будет?

Две полусферы соединяются на защелку, и чтобы нажалась кнопка, нужно будет лишь сжать их между собой. Снаружи ни каких кнопок не будет.

strarbit
Offline
Зарегистрирован: 12.06.2016

КРУТО)

Joiner
Offline
Зарегистрирован: 04.09.2014

strarbit пишет:

КРУТО)

И мне тоже нравится :)

Joiner
Offline
Зарегистрирован: 04.09.2014

Сегодня завершил свой супер проект!!! Все получилось https://youtu.be/nhHyAi4Ica0

А не замахнуться ли нам.......на шар с дисплеем?

b707
Offline
Зарегистрирован: 26.05.2017

Шикарно.

один из лучших проектов на форуме, кмк :)

Joiner
Offline
Зарегистрирован: 04.09.2014

Спасибо