воскресенье, 25 апреля 2010 г.

Лампа настроения, убдате..

“Аналитическое тупление” дало результаты, код изменился, хотя результат работы тот же – плавная смена цветов по кругу:

   1: #include <;;avr/io.h> 
   2: #include <;;avr/interrupt.h> 
   3: #include <;;avr/pgmspace.h> 
   4: #include "avrlibtypes.h" 
   5: #include "delay.h" 
   6:  
   7: #define F_OSC F_CPU 
   8:  
   9: volatile u08 r, g, b, counter = 0; 
  10: 
  11: // таблица нелинейности для яркости 
  12: // хотя как лучше – с ней или без – я пока не решил 
  13: // если без нее – тогда можно не включать pgmspace.h и выкинуть 2 строки из 
  14: // след. функции (v = pgm_…) 
  15: u08 gamma[256] PROGMEM = { 
  16:     0,   1,   1,   2,   2,   2,   2,   2,   2,   3,   3,   3,   3,   3,   3,   3, 
  17:     3,   3,   3,   3,   3,   3,   3,   4,   4,   4,   4,   4,   4,   4,   4,   4, 
  18:     4,   4,   4,   5,   5,   5,   5,   5,   5,   5,   5,   5,   5,   6,   6,   6, 
  19:     6,   6,   6,   6,   6,   7,   7,   7,   7,   7,   7,   7,   8,   8,   8,   8, 
  20:     8,   8,   9,   9,   9,   9,   9,   9,   10,  10,  10,  10,  10,  11,  11,  11, 
  21:     11,  11,  12,  12,  12,  12,  12,  13,  13,  13,  13,  14,  14,  14,  14,  15, 
  22:     15,  15,  16,  16,  16,  16,  17,  17,  17,  18,  18,  18,  19,  19,  19,  20, 
  23:     20,  20,  21,  21,  22,  22,  22,  23,  23,  24,  24,  25,  25,  25,  26,  26, 
  24:     27,  27,  28,  28,  29,  29,  30,  30,  31,  32,  32,  33,  33,  34,  35,  35, 
  25:     36,  36,  37,  38,  38,  39,  40,  40,  41,  42,  43,  43,  44,  45,  46,  47, 
  26:     48,  48,  49,  50,  51,  52,  53,  54,  55,  56,  57,  58,  59,  60,  61,  62, 
  27:     63,  64,  65,  66,  68,  69,  70,  71,  73,  74,  75,  76,  78,  79,  81,  82, 
  28:     83,  85,  86,  88,  90,  91,  93,  94,  96,  98,  99,  101, 103, 105, 107, 109, 
  29:     110, 112, 114, 116, 118, 121, 123, 125, 127, 129, 132, 134, 136, 139, 141, 144, 
  30:     146, 149, 151, 154, 157, 159, 162, 165, 168, 171, 174, 177, 180, 183, 186, 190, 
  31:     193, 196, 200, 203, 207, 211, 214, 218, 222, 226, 230, 234, 238, 242, 248, 255 
  32: }; 
  33: 
  34: void getRGB (u16 h, u08 s, u08 v) 
  35: { 
  36:   u16 base; 
  37: 
  38:   v = pgm_read_byte(&gamma[v]); 
  39:   s = 255 - pgm_read_byte(&;;gamma[255 - s]); 
  40:  
  41:   if (s == 0) 
  42:   { 
  43:     r = v; 
  44:     g = v; 
  45:     b = v; 
  46:   } else { 
  47:     base = ((255 - s) * v) >;;> 8; 
  48:  
  49:     switch (h / 60) { 
  50:       case 0: 
  51:         r = v; 
  52:         g = (((v - base) * h) / 60) + base; 
  53:         b = base; 
  54:         break; 
  55:       case 1: 
  56:         r = (((v - base) * (60 - (h % 60))) / 60) + base; 
  57:         g = v; 
  58:         b = base; 
  59:         break; 
  60:       case 2: 
  61:         r = base; 
  62:         g = v; 
  63:         b = (((v - base) * (h % 60)) / 60) + base; 
  64:         break; 
  65:       case 3: 
  66:         r = base; 
  67:         g = (((v - base) * (60 - (h % 60))) / 60) + base; 
  68:         b = v; 
  69:         break; 
  70:       case 4: 
  71:         r = (((v - base) * (h % 60)) / 60) + base; 
  72:         g = base; 
  73:         b = v; 
  74:         break; 
  75:       case 5: 
  76:         r = v; 
  77:         g = base; 
  78:         b = (((v - base) * (60 - (h % 60))) / 60) + base; 
  79:       break; 
  80:     } 
  81:   } 
  82: } 
  83:  
  84: void init(void) 
  85: { 
  86: //{{AVR_IO_DESIGNER_INIT 
  87:     // Project Options - ambi-lamp 
  88:     // 
  89:     // Device Name = ATtiny2313 
  90:     // CPU Frequency (F_CPU) = 11,059 MHz 
  91:     // IC Package = DIP 
  92:     // Sort Pins by = Pin Number 
  93:     // Output Code File = ..\main.c 
  94:     // Output Header File = ..\hardware.h 
  95:     // Assume Default State = True 
  96:     // Write Unmodified Bits = True 
  97:     // Set Unused PORT Pins = Input 
  98:  
  99:     // 
 100:     // PORTD variable initializations 
 101:     // 
 102:     // PORTD3 for 1: led_red as Output - 
 103:     // PORTD4 for 1: led_green as Output - 
 104:     // PORTD5 for 1: led_blue as Output - 
 105:     DDRD = 0x38; 
 106: 
 107:     // 
 108:     // TIMER_COUNTER_0 -  - 
 109:     // 
 110:     // Clock Select = clk (No prescaling) 
 111:     // Timer Overflow Interrupt Enable = Enabled 
 112:     // Counter Frequency = 43,199 kHz 
 113:     // Counter Period = 23,149 usec 
 114:     // Seconds per Count = 90,424 nsec 
 115:     // Counts per Second = 11,059 MHz 
 116:     TIMSK = 0x02;    // (1<<TOIE0) 
 117:     TCCR0B = 0x01;    // (0<<CS02)|(0<<CS01)|(1<<CS00) 
 118: //}}AVR_IO_DESIGNER_INIT 
 119:  
 120:     sei(); 
 121: } 
 122:  
 123: ISR(TIMER0_OVF_vect) 
 124: {
 125:  
 126: #define    led_red_SHIFT           0x03 
 127: #define    led_green_SHIFT         0x04 
 128: #define    led_blue_SHIFT         0x05 
 129:  
 130:   PORTD = ((r >;; counter) << led_red_SHIFT) | ((g > counter) << led_green_SHIFT) | 
 131:           ((b >;; counter) << led_blue_SHIFT); 
 132:   counter++; 
 133: } 
 134:  
 135: int main(void) 
 136: { 
 137:   init(); 
 138: 
 139:   u16 h; 
 140:  
 141:   while(1) 
 142:   { 
 143:     for (h = 0; h < 360; h++) 
 144:     { 
 145:       // ф-ция принимает параметр – цвет, насыщенность и яркость 
 146:       // цвет от 0 до 360 == от красного к фиолетовому по радуге 
 147:       // насыщенность == 255 – “чистый” цвет, ближе к 0 – “серый”; на цветовом конусе это означает, что с 
 148:       // минимальной насыщенностью с изменением цвета тот собственно практич. не меняется – в моем 
 149:       // случае это практич. белый с любым значением цвета 
 150:       // яркость понятно, чем меньше, тем ближе к черному.. при маленьких значениях начинаются глюки в виде мерцания.. 
 151:       // з.ы. глюки больше (при маленьких значениях насыщенности и яркости) без корректирующей таблицы, с 
 152:       // другой стороны – таблица == четверть памяти контроллера (прошивка занимает 1400/1100 байт с и без таблицы) 
 153:       getRGB(h, 255, 150); 
 154: 
 155:       delay_ms(10); 
 156:     } 
 157:   } 
 158:  
 159:   return 0; 
 160: }

2 комментария:

  1. Сделал себе аналогичную лампу.

    Менять цвета по кругу - как-то скучно. Это проще выдрать мозги из китайского снежка.

    Что б меньше мучиться с выбором подходящего алгоритма - записал несколько различных вариантов работы (цикл основных цветов, рандомно из основных, полный рандом, фиксированный цвет и т.п.)
    Теперь добавлю и вашу идею - рандомное движение по колесу. По сути это получится как цикл основных цветов, но с различной скоростью движения (включая отрицательную).

    Питание - от miniUSB. Найти дома лишнюю зарядку для телефона сейчас не проблема. Можно и к пк подсоединить (только не к ноуту, тока не хватит). Через ПК можно заодно и откорректировать основные параметры (скорость смены, фикс. цвет и пр., возможно добавлю полоностью программируемую подпрограмму), а так же перехватить управление цветом. Тут уже можно использовать лампу как ambX (почти как амбилайт), или как светомузыку. Да и вообще можно хоть движение мыши отслеживать, добавить в софт - не проблема.
    Получился в итоге маленький космический корабль. Нужен ли он, когда почти все время лампа будет гореть в одном режиме? Может и нет. Зато такого у китайцев точно не найдешь =)

    P.S.
    Коррекция гаммы не очень-то и нужна. Лампе не требуется точная цветопередача.
    С цветопередачей только один минус - чистый белый цвет поймать сложно.

    ОтветитьУдалить
  2. ну понятно, что по кругу неинтересно.. просто с getRGB можно теперь играться и цветом, и яркостью (хотя там на малых яркостях глюки начинаются, не разбирался, из-за чего, наверное теряются значения при умножениях\делениях).. оставшиеся пол-памяти можно использовать, чтобы подключить софтварный usb (http://www.recursion.jp/avrcdc/cdc-232.html#usage например).. не нашел правда быстро, сколько ему мин. памяти надо для реализации

    а таблица коррекции в данном случае используется не для уточнения цветопередачи, а для компенсации изменения яркости, точнее того факта, что глаз 75 и 100% яркости уже не различит (и с ней глюков кардинально меньше на маленьких яркостях)

    ОтветитьУдалить