3本の目が柱にかかっている、またはATtiny13の5本の足で十分だという話



KDPV「ああ、それだけだ。」







このロングライドが、カルノーカードの占いの秘密に精通し、第三標準形の秘密の意味を知る、知識人の生命を与える知恵の源となる可能性はほとんどありません。 しかし、何らかの理由で手でアルドゥイーノに触れた場合、はんだごてがパントリーにほこりを集めていると、バッテリーにプラスが1つ、C ++に2つある理由がわかります。本当に魔法のような素晴らしい奇跡はあなたを無関心にしません。 だから、私はあなたにサーカス「ツゲの木とサマン」の旅行サーカスの今日のパフォーマンスの数をお勧めする喜びがあります:









20人の読者全員に少なくとも1つのトリックが将来役に立つなら、この記事は無駄に書かれていないと満足するでしょう。







最初の信号またはKaaが戦います。



物語は、古典的なクリスマスアドベントビデオカメラのように、カメラがすりガラスの窓から小さな居心地の良い部屋を見たときから始まりました。見掛け倒しのクリスマスツリー、コットンウール、おもちゃ、マンダリンとグリューワインの香り、ろうそくの明かりからの暖かい震えです。 大きなソファで、彼女は格子縞をまっすぐにし、頬を優しく彼の肩に押し付け、熱狂的に身振りで示す天使のような少女をぼんやりと聞いて......







親の経験がある人は、そのような瞬間にあなたが聞くことができるものを完全によく知っています。 まだそのようなスキルを習得していない人に説明します-かなりの確率で、親は次のようなものにd然としています。 明日! 幼稚園へ! しなきゃ! クリスマスツリーコンテストに工芸品をお持ちください! そして、私は最初の場所が欲しい!」







必要です。 明日。 私たちに。 工芸品。 最高。







顧客に関するインタビューは、作業明細書の輪郭を示しています。信号機が必要です。 そして、美しくなり、本物のように輝きます。 すでにこの段階で、ISUプロジェクトの候補者のランクは劇的に低下しています。パパは、可愛くて柔らかく、細断された、編み物またはかぎ針編みの信号から縫い付けられたものが顧客の夢の具現化された表現であるという考えを実証することはできません。







夜は国中を転がり、わが国では仕事が沸騰し始めました。







信号機の本体材料はトイレットペーパーのスリーブで、箱が折り返されるように圧着されています。 10ルーブルコインを鉛筆で囲み、光信号の光の下で事務用ナイフで穴を切りました(外傷性の作業は子供には信頼されていません)。













信号機の上部と下部のカバーは、所定の位置にある段ボールから切り取られます。 作られたパターンに従ってランプの上のピークは通常の80グラムの紙に輪郭を描かれ、手動で切り取られました。













その後、PVAに接着されました。













組み立てられた構造は中庭に引き出され、アクリルスプレーペイントで塗装されました。













いずれかの段階で損傷が発生した場合、一度に3つのコピーが作成されました。 赤、黄、緑-色紙の最も成功した貼り付けられた3つのストリップ内の光フィルター。







内側からの照明は、祖国の寛大なビン(SHZR)からの一対の超高輝度白色LEDによって決定されました。 Kaptershchitskayaのヒキガエルは、3個のタブレットリチウム電池さえもSCHRの存在の父に明かすことを拒否し、LEDは白から明るく、それらの電圧降下は2.8から3.9ボルトであると述べて、1個からの輝きに同意しませんでした。 私たちがヒキガエルと交渉した最大値は、単三電池1本、焼けたマザーボードのスロットルからのフェライトリング、およびKT315トランジスタでした。 お父さんは考えてグーグルで申し出を受け入れなければなりませんでした。 そして、幼稚園の各グループの遊び心のあるペンの数を考えると、リチウム電池のアイデアは特に魅力的に見えませんでした。







バッテリーの信号機の外皮は針とみかんの香りをひどいペンキの香りに置き換え、父は思慮深くロジンにはんだごてを突っ込んで、子供たちは発電機をブロックするための変圧器を巻きました(コピーの複製)...







いいえ、その夜は「突然」ではありませんでした。変圧器を巻くときのすべてのトリックは、可能な限り最大の巻き数を2重のワイヤですぐに巻くことです。 LEDのアノードとカソード、およびKT315トランジスタの端子を混同しないでください。また、回路図に従って巻線の端を正しく接続(または点灯していない場合は交換)しないでください。 J1-後に信号機の「屋根の上」に表示されるコンピュータージャンパーの電源スイッチ。







1.5V G1バッテリーから3〜7Vのピークを持つAC電圧を生成するための完全に単純なスキームは、 広く知らています。













物理的に、回路図は次のように具体化されます。













赤テープ-単三アルカリ電池。







そして、信号機自体はそのようなものです。













朝、誇らしげな子供がこの製品を幼稚園に引きずり、そこでおもちゃが飛び散り、クリスマスツリーの中心になりました。













確かに、それは競争の最初の場所でうまくいきませんでした-判明したように、作品を提出する期限はすでに数日前でした。







自宅では、窓辺に2つの建物があり、父は「本物の信号機のようにしたい」タスクの解決策にitい不満を抱いていました。 そしてアイデアは次のように回転していました:「ヒキガエルが長い間ShchZRに横たわっているという完全な解決策を適合させることは可能ですか?コード用のキロバイトとRAMの64バイト、そして注文どおりに、本物のように十分な5つのレッグがありますか?」







したがって、これはただのことわざであり、今後の信号問題の最終的な解決策についてのおとぎ話です。







本物のような2番目の信号



使用済みのツール、材料、ドキュメント



言語/フレームワーク :C / Arduino 1.6 / 1.8。

IDE :MS Visual Studio 2012 + Visual Microプラグイン+ git。

CAD :DipTrace。

HW :MK ATtiny13、ATmega328上のArduino Nanoクローン、FT232R上のUSB-UART、china-noname USBISPプログラマー。

PPテクノロジーLUT

ツール :はんだごて、グルーガン、キッチンオーブン、ナイフ、はさみ、ワイヤーカッター。

材料SHCHZRから-nonameブランドの赤、黄、緑の出力LED 4個、SMDタンタルコンデンサー、抵抗10805、各10k、半ダース出力0.25W電流制限抵抗MF-25、中国製ブーストDC-DC 5Vコンバーター、エアゾール缶銀と黒の塗料、A4紙、販売からのポリマー粘土。







ソースとドキュメントは、MITライセンスの下でGithubで利用できます。ソースコードのコミットは、以下で説明するファームウェアの反復と一致します。記載されているすべてのファイルパスは、リポジトリのルートに関連しています。







ドキュメント

./docs/ATtiny13A datasheet.pdf [MK Atmel ATtiny13Aの仕様]

./docs/ATmega328 datasheet.pdf [Atmel ATmega328 MK仕様]

./docs/AVR4027-C Code.pdfを最適化するためのヒントとコツ[Atmel AVR4027:8ビットAVRマイクロコントローラー用にCコードを最適化するためのヒントとコツ]

./docs/AVR4013-PicoPower basics.pdf [省電力モードに関する注意事項]







Arduino IDEから、クラウドの毛布のように。 彼らのウィズは、組み込みプログラマーの間で神聖になることができるすべてのイエズス会の微妙なock笑です。 しかし、Arduinoは、さまざまなOSのコンピューターに環境をインストールするのが簡単であり、ハードウェアデバッガーに特別な費用をかけることなく、ペニーUARTと独自のブートローダーを使用して最初に有効にしたため、生態系として生き続け、生き続けます。かなり深刻なMK充填の開発。 そして、ここにアンクル・リャオがいます。一握りのクローンをオリジナルの価格で販売する準備ができています。 シニアatmegsでは、プログラムのロジックと動作をデバッグでき、同じティンカに転送するための最小限の変更を加えることができるという事実-これも議論です。







MS VisualStudioで作業するのは普通で快適です。AtmelStudioやWinAVRのスペースがあまりないので、 ハードウェアデバッガーがないと、究極のアメニティがありません。 MS VisualStudioにArduinoのサポートを追加するVisualMicroプラグインについては、 すでに十分詳細に記述されており、Haberにインテリジェントに記述されています。

ハブでの「Arduino on ATtiny13」の焦点も、 かなり前から繰り返し 検討されていました。







簡単に説明すると、インストールされているArduino環境のインストールにMicroCoreモジュールを追加すると、ATtiny13 MKターゲットを選択できるようになります。













Git-どんなホームプロジェクトでも、代替手段はありません。 習慣は簡単ですが、正しいです。プログラムで作業を開始するときは、コマンドラインのディレクトリに「git init」と入力するだけです。 ローカルリポジトリでのコミットに対するMS Visual Studioの組み込みサポートにより、時間と時間を何度も節約できます。







DipTraceは、回路およびプリント基板用のCADのように、便利で家庭用で、回路と配線は使いやすく、必要に応じてカスタムコンポーネント(UGO、コンタクト)を簡単に追加できます。 さらに、私は彼らのライセンスポリシーに感銘を受けました。ロシア、ウクライナ、ベラルーシ共和国では無料である非営利標準ライセンス(1000ピン、4信号層)の制限は、99%のケースでホームクラフトに十分です。







私は、Arduino Nanoを小さなプログラマーとして適切に動作させることができませんでしたが、USB ISPプログラマーでは、問題は簡単に解決されます。 プロジェクトの./gccディレクトリにあるコンパイル/ファームウェア用のバッチファイルをすばやくスケッチしました。







.inoファイル(実際はC / C ++)は、「ATtiny13のarduinoの下」のスタジオで正しくコンパイルできます。コマンドラインでこのバッチファイルのパラメーターを使用するだけです。







>"./gcc/0_MAKE & upload.cmd" MyArduinoFile.ino
      
      





ISP , , .







>"./gcc/0_MAKE & asm.cmd" MyArduinoFile.ino
      
      





, , — , AVR . : , .









Upgrade ROM&RAM Arduino ATtiny13



Arduino ( setup(){...}; loop(){...};) "" - int main(){setup(); loop();}, by Arduino.







uint8_t cnt;
void setup() {
    cnt=0;
}
void loop() {
  cnt++;
}
//Program size: 164 bytes (used 16% of a 1 024 byte maximum) (0,57 secs)
//Minimum Memory Usage: 5 bytes (8% of a 64 byte maximum)
      
      





, :







uint8_t cnt;
int main(){
    cnt=0;      // < setup()
    while(1){
        cnt++;  // < loop()
    }
}
//Program size: 60 bytes (used 6% of a 1 024 byte maximum) (1,23 secs)
//Minimum Memory Usage: 1 bytes (2% of a 64 byte maximum)
      
      





16% 6% , , 6% . , — 64 .









, , : . , , , , . , , , . , : CPU , . — , N . ""-CPU , (9.6 / 1024 = 9370 , ) 1/9370 = 0.0001067 . 8- . , , , " ". , , , "". 37 (256 0.0001067 = 0.027315; 0.027315 37 = 1.01065 ~= 1s).







: - (HW , 1024 ), 8 — , , .







: globalTimer volatile, , , , CPU , .







#include <avr/io.h>         //     IDE -  
#include <avr/sleep.h>      // ,  
#include <avr/interrupt.h>          //   
volatile uint16_t  globalTimer;     //     64   
//  -    globalTimer  1/37 
ISR(TIM0_OVF_vect){
    globalTimer++;  //       . , ,  while(1)   .
}
int main() {
    //     "  -". 
    set_sleep_mode(SLEEP_MODE_IDLE);    //   - .
    sleep_enable();                 //    
    TCCR0B = _BV(CS02) | _BV(CS00); //  0 - clock frequency / 1024
    TIMSK0 |= _BV(TOIE0);           //      overflow interrupt
    sei();                          //    
    while(1){
        //.........   
        sleep_cpu();    //     -   .
    }
}
//Program size: 128 bytes (used 13% of a 1 024 byte maximum) (0,86 secs)
//Minimum Memory Usage: 2 bytes (3% of a 64 byte maximum)
      
      





" 4 : , , "()



, , .

, , CPU, / / . GPIO.







Arduino : Arduino pin_number ( ):







pinMode(pin_number, OUTPUT); //   INPUT -   
      
      





/ , — .







Value = digitalRead(pin_input_number);  //Value -  HIGH  LOW (1  0)
digitalWrite(pin_outpit_number, Value);       //   pin_outpit_number - HIGH  LOW
      
      





"" , Wiring , , Arduino ( ) ( ) ( ) ( ).













.. Arduino 7 11 PD7 — D.

digitalRead, digitalWrite, pinMode .., , , , Wiring- , .







— , . , DIHALT .













- (GPIO) , 8- — 8 . , 6 (. ATtiny13 pinout, ), PB0 PB5, PB5 — MK . - : ( "B") DDRB, PINB PORTB. — , , . PB0, PB1, PB2, PB3, PB4, PB5 — B. #include <avr/io.h> ( iotn13.h ), (PB0 0,..., PB5 — 5) IDE, Arduino.







: , , . , - , , , DDRx GPIO , — . PORTx — , "- ", , — , PINx. , 50 0 1. , .







,

PB2 HIGH, +5, PB3 LOW, 0, PB0 , — .

DDRB , PB0, ( ) = 0 (PB0 ), = 1 (PB2, PB3 — ), .. 110, — , 1 0 — .







DDRB = 12;  //  000001100    - 12
//        (!)
//        pinMode().
      
      





— PORTB , =1 (PB2 HIGH), — (PB3 LOW), — , 01







PORTB = 8;  //(dec)8 === (bin)000001000
//  -        .
      
      





PINB, , — .

, — .

3 (PB3) : 1 , 3 .

3<<00000001 === PB3<<1 // — 00001000

, _BV(x), (x<<1), .. _BV(PB3) — 1.

_BV(PB3) | _BV(PB2) 00001100 (| — ).

: , , .







PORTB |= _BV(PB3) | _BV(PB2); // 2  3   == 1,     PB2  PB3  HIGH,   PORTB  
      
      





0 , , . 0 1 . , , 1 , 0 — 0 .







PORTB &= ~(_BV(PB3) | _BV(PB2)); //   PORTB 2  3  -  , LOW,   .
      
      





HW , - 0, Timer0. GPIO, , , datasheet ATtiny13, - -, Ilya Ananev - 0 ATmega328.







, , .







TCCR0B = _BV(CS02) | _BV(CS00);    //    CS02  CS00  1 -   0 = clock frequency / 1024
TIMSK0 |= _BV(TOIE0);           //   TOIE0  1 -     TIM0_OVF
//      TIMSK0 = _BV(TOIE0);
      
      





.



, . , , . - , , , (!) .







, . " 27.02.13" 7 52289-2004 , .

( ): , , , , , .







"* " " 2 , — 3 .







3 1 /.*"







, ( , / — PERIOD_0 PERIOD_4, — ).







#define ONE_SECOND  37      //     1 
#define QT_SECOND   9       //  

#define PERIOD_FLASH_GREEN  QT_SECOND           //    ( ) -    
#define PERIOD_FLASH_YELLOW ONE_SECOND * 1      //    -    - 
                                                        //  --- 
#define PERIOD_0    ONE_SECOND * 10 //R G R G   0.  ---   (10 )
#define PERIOD_1    ONE_SECOND * 3  //R g R g   1.  ---   (3 )     
#define PERIOD_2    ONE_SECOND * 1  //R Y R Y   2.  ---  (1 )
#define PERIOD_3    ONE_SECOND * 2  //RY Y RY Y 3. + ---  (2 ) 
#define PERIOD_4    ONE_SECOND * 7  //G R G R   4.  ---   (7 )
#define PERIOD_5    ONE_SECOND * 3  //g R g R   5.   --- (3 )
#define PERIOD_6    ONE_SECOND * 1  //Y R Y R   6.  ---  (1 )
#define PERIOD_7    ONE_SECOND * 2  //Y RY Y RY 7.  --- + (2 )
      
      





, , .







typedef struct{
    const uint8_t ddr_val_0;    // DDRB value -   
    const uint8_t port_val_0;   // PORTB value   -   
    const uint8_t ddr_val_1;    // DDRB value  -   "",   
    const uint8_t port_val_1;   // PORTB value - 
    const uint16_t flash_period;    // period of flashing -   _val_1  _val_0
    const uint16_t signal_period;   // period of this lighting state
}lightSignalization;            //   , _0  _1 -   , flash_long -   
// flash_period == 0,   ,   _val_0.
// signal_period == 0,         .
      
      





, 128 — , .







ATtiny13 ( ?) -



, , - - , : 6 . - denvo " ? RESET" 5- , , , , - .







- : --, .. , 7 .







— , , , 8, ?







, -, "reset", PB5, .







, ? , , , . , , , , , .







, , 8 9 - , 8 — . , -, , , , .







— .







: — . .







:













1 PORTB |= _BV(GREEN_PIN) — ( ) , 0 .. PORTB &= ~(_BV(GREEN_PIN)) — ( ).

, , ?

(DDRB |= _BV(GREEN_PIN)) , DDRB &= ~(_BV(GREEN_PIN)), GREEN_PIN Hi-Z . (2.2 * 4) 5, .







.

— .. , , .







, ,

, . , — , 37/2=18 , , . :

) , , , , ;

) — , " " 4 ;

) , 4 ( PERIOD_2->PERIOD_3 PERIOD_6->PERIOD_7);

) 4 .







.













// PINB === 0 0 0 g r y0 btt y1
#define RED_PIN     PB3     // OUT: 1 - "-" , 0 - "-" , IN -  , ,  (!) 
#define YELLOW0_PIN PB2     // OUT: 1 -  "-" 
#define YELLOW1_PIN PB0     // OUT: 1 -  "-" 
#define GREEN_PIN   PB4     // OUT: 1 - "-" , 0 - "-" , IN -  , ,  (!) 

#define RED     _BV(RED_PIN)        // _BV -     (), 1<<VALUE
#define YELL0   _BV(YELLOW0_PIN)        //    -
#define YELL1   _BV(YELLOW1_PIN)
#define GREEN   _BV(GREEN_PIN)      //    - (  0 -   -)  DDRB.GreenPin=1
      
      





. , , — , .







#define BUTTON_PIN      PB1
#define BUTTON_ON  !(PINB & _BV(BUTTON_PIN))    //( (PINB & _BV(BUTTON_PIN)) == 0)  //  " " -   LOW
#define BUTTON_OFF (PINB & _BV(BUTTON_PIN))     //  " " -    HIGH, (     )
      
      





, , n ( ) n(n−1) = n²−n . 4 12 , . « , » « , » .







12 LED







*** — , DDRx|PORTx, , .. . — , , .







.***







: ?



lightSignalization. lightSignalization . 0 7 , 8 — , 9 — , "" . , 0 7, . , , . 3 ( 0 7) 8 -- . if- , . , .







lightSignalization traffic_signals[] = {//   
 // {DDRB0, PORTB0,   DDRB_when_flashingif, PORTB_when_flasingif (if flashing),   continous of half-period flashing,   continous curr mode runing}
    {RED|GREEN, RED,   0, 0,   0, PERIOD_0},                    // R G R G
    {RED, RED,  RED|GREEN, RED,   QT_SECOND, PERIOD_1},     // R g R g - flash east green
    {RED|YELL1, RED|YELL1,   0, 0,   0, PERIOD_2 },         // R Y1 R Y1
    {RED|YELL0|YELL1, RED|YELL0|YELL1,  0, 0,   0, PERIOD_3 },  // RY0 Y1 RY0 Y1
    {RED|GREEN, GREEN,   0, 0,   0, PERIOD_4},              // G R G R
    {RED|GREEN, GREEN,   RED, 0,    QT_SECOND, PERIOD_5 },  // g R g R - flash nord green
    {RED|YELL0, YELL0,   0, 0,   0, PERIOD_6},                  // Y0 R Y0 R
    {RED|YELL0|YELL1,  YELL0|YELL1,   0, 0,   0, PERIOD_7  },       // Y0 RY1 Y0 RY1

    {YELL0|YELL1, YELL0|YELL1,   YELL0|YELL1, 0,  ONE_SECOND, 0},   // y0 y1 y0 y1 - flash yellows lights 
    {0, 0,   0, 0,   0, 0}          // traffic lights off, DDR in, Hi-Z
};

//       lightSignalization traffic_signals[]
#define LIGHT_NUM_YELLOW_FLASH  8       //       -  - flash yellows lights
#define LIGHT_NUM_STD_START     0       //       
#define LIGHT_NUM_LIGHTS_OFF    9       //      -   - traffic lights off
      
      





lightSignalization 8 . .. traffic_signals[] 10 80 (, 64 , 2 ). , .







, , , — ROM, , RAM , .







-







const lightSignalization traffic_signals[] PROGMEM= {...
      
      





,







<avr/pgmspace.h> pgm_read_byte_near()  pgm_read_word_near()
      
      





char shortint .







3 .







  1. , .

    traffic_signals[] — LIGHT_NUM_LIGHTS_OFF

    {0, 0, 0, 0, 0, 0} // traffic lights off

    — lightSignalization , — , lightSignalization.signal_period==0 (.. ), lightSignalization.flash_period==0, .. .







  2. , .

    traffic_signals[] — LIGHT_NUM_YELLOW_FLASH

    {YELL0|YELL1, YELL0|YELL1, YELL0|YELL1, 0, ONE_SECOND, 0}, // y0 y1 y0 y1 — flash yellows lights

    : lightSignalization.signal_period==0. lightSignalization.flash_period=ONE_SECOND, :







    DDRB = YELL0|YELL1;     // YELL0, YELL1 - 
    PORTB = YELL0|YELL1;    // YELL0, YELL1 = HIGH -  
          
          











    DDRB = YELL0|YELL1;     // // YELL0, YELL1 -   
    PORTB = 0;              // YELL0, YELL1 = LOW -  
          
          





  3. , --.









, .







traffic_signals[] — LIGHT_NUM_STD_START

{RED|GREEN, RED, 0, 0, 0, PERIOD_0}, // R G R G

: lightSignalization.flash_period==0.

DDRB = RED|GREEN; //RED GREEN — , .

PORTB = RED; // RED — HIGH (- )

// GREEN — LOW ( , - — )

lightSignalization.signal_period==PERIOD_0, .







current_signal. 2 — , lightSignalization.







uint8_t current_signal;     // 1    ,   traffic_signals
uint16_t tl_flash_end;      // 2       ( !0), 
uint16_t tl_signal_end;     // 2            ( !0)
      
      





tl_signal_end != 0, globalTimer>tl_signal_end current_signal. 0 current_signal, 3, .

current_signal = current_signal & B00000111;







current_signal &= LIGHT_NUM_STD_MASK ;   //current_signal & B00000111;
      
      





current_signal , 0 7.

globalTimer — .







#include <limits.h>         // USHRT_MAX
#include <avr/sleep.h>      // ,  
#include <avr/interrupt.h>  //   
#include <avr/pgmspace.h>   //    

#define ONE_SECOND  37      //     1 
#define QT_SECOND   9       //  
#define MAX_GLOBAL_TIMER_VALUE  (USHRT_MAX / 2)     // uint16_t globalTimer -   . 65535 /2 
//     ,  MAX_GLOBAL_TIMER_VALUE - 1
#define PERIOD_FLASH_GREEN  QT_SECOND           //    ( ) -    
#define PERIOD_FLASH_YELLOW ONE_SECOND * 1      //    -    - 
                                                        //  --- 
#define PERIOD_0        ONE_SECOND * 10     //R G R G   0.  ---   (15 )
#define PERIOD_1        ONE_SECOND * 3      //R g R g   1.  ---   (3 )     
#define PERIOD_2        ONE_SECOND * 1      //R Y R Y   2.  ---  (1 )
#define PERIOD_3        ONE_SECOND * 2      //RY Y RY Y 3. + ---  (2 ) 
#define PERIOD_4        ONE_SECOND * 7      //G R G R   4.  ---   (10 )
#define PERIOD_5        ONE_SECOND * 3      //g R g R   5.   --- (3 )
#define PERIOD_6        ONE_SECOND * 1      //Y R Y R   6.  ---  (1 )
#define PERIOD_7        ONE_SECOND * 2      //Y RY Y RY 7.  --- + (2 )

typedef struct{
    const uint8_t ddr_val_0;    // DDRB value    
    const uint8_t port_val_0;   // PORTB value  
    const uint8_t ddr_val_1;    // DDRB value    
    const uint8_t port_val_1;   // PORTB value
    const uint16_t flash_period;    // period of flashing -   _val_1  _val_0
    const uint16_t signal_period;   // period of this lighting state
}lightSignalization;            //   , _0  _1 -   , flash_long -   

//    (PINS === 0 0 0 g r y0 btt y1):
 //     ""     
#define BUTTON      PB1
#define RED_PIN     PB3     // OUT: 1 - "-" , 0 - "-" , IN -  , ,  (!) 
#define YELLOW0_PIN PB2     // OUT: 1 -  "-" 
#define YELLOW1_PIN PB0     // OUT: 1 -  "-" 
#define GREEN_PIN   PB4     // OUT: 1 - "-" , 0 - "-" , IN -  , ,  (!) 

#define BUTTON_ON  !(PINB & _BV(BUTTON))    //( (PINB & _BV(BUTTON)) == 0)  //  " "
#define BUTTON_OFF  (PINB & _BV(BUTTON))    // ~(PINB & _BV(BUTTON)) -\\- " "

#define RED     _BV(RED_PIN)            // _BV -     (), 1<<VALUE
#define YELL0   _BV(YELLOW0_PIN)        //
#define YELL1   _BV(YELLOW1_PIN)
#define GREEN   _BV(GREEN_PIN)

//       lightSignalization traffic_signals[]
#define LIGHT_NUM_YELLOW_FLASH  8       //       -  - flash yellows lights
#define LIGHT_NUM_STD_START     0       //       
#define LIGHT_NUM_LIGHTS_OFF    9       //      -   - traffic lights off
#define LIGHT_NUM_STD_MASK      7       // ___++ &LIGHT_NUM_STD_MASK -    0  7   

//....................................  
// 
const lightSignalization traffic_signals[] PROGMEM= {   //   ,  ,   -, PINS === 0 0 0 g r y0 btt y1
 // {DDRB0, PORTB0,   DDRB_flashing, PORTB_flasinf (if flashing),   continuous of half-period flashing,   continuous id mode running}
    {RED|GREEN, RED,   0, 0,   0, PERIOD_0},                    // R G R G
    {RED, RED,  RED|GREEN, RED,   QT_SECOND, PERIOD_1},     // R g R g - flash east green
    {RED|YELL1, RED|YELL1,   0, 0,   0, PERIOD_2 },             // R Y1 R Y1
    {RED|YELL0|YELL1, RED|YELL0|YELL1,  0, 0,   0, PERIOD_3 },  // RY0 Y1 RY0 Y1
    {RED|GREEN, GREEN,   0, 0,   0, PERIOD_4},                  // G R G R
    {RED|GREEN, GREEN,   RED, 0,    QT_SECOND, PERIOD_5 },      // g R g R - flash nord green
    {RED|YELL0, YELL0,   0, 0,   0, PERIOD_6},                  // Y0 R Y0 R
    {RED|YELL0|YELL1,  YELL0|YELL1,   0, 0,   0, PERIOD_7  },   // Y0 RY1 Y0 RY1

    {YELL0|YELL1, YELL0|YELL1,   YELL0|YELL1, 0,  ONE_SECOND, 0},   // y0 y1 y0 y1 - flash yellows lights 
    {0, 0,   0, 0,   0, 0}              //  traffic lights off, 
};

volatile uint16_t  globalTimer;     //     64   
uint8_t current_signal;     // 1    ,   traffic_signals
uint16_t tl_flash_end;      // 2       ( !0), 
uint16_t tl_signal_end;     // 2            ( !0)

//....................................  
void setPeriods(uint8_t num, bool set_both_flash_and_signal);   //  tl_flash_end, tl_signal_end
void setPorts(uint8_t num, bool use_main_values);               //    

//....................................  
//
//  -    globalTimer  1/37 
ISR(TIM0_OVF_vect){
    globalTimer++;  //       . ,   while(1)   .
}

int main() {
//
bool use_main_values = true;            // lightSignalization._val_0 (1)  lightSignalization._val_1 (0)? -  
current_signal = LIGHT_NUM_STD_START;   //   .     .

    //     "  -". 
    set_sleep_mode(SLEEP_MODE_IDLE);    //   - .
    sleep_enable();                 //    

    TCCR0B = _BV(CS02) | _BV(CS00); //  0 - clock frequency / 1024
    TIMSK0 |= _BV(TOIE0);           //      overflow interrupt

    sei();      //    
    while(1){
        //   ? 
        if(globalTimer > MAX_GLOBAL_TIMER_VALUE){
            globalTimer -= MAX_GLOBAL_TIMER_VALUE;          //   
            // 
            if(tl_flash_end){
                tl_flash_end -= MAX_GLOBAL_TIMER_VALUE;     //   ,  
            }
            if(tl_signal_end){
                tl_signal_end -= MAX_GLOBAL_TIMER_VALUE;    // //   ,  
            }
            // setPeriods(currentMode, false); //   12  ,  tl_.._end   ,     
        }

                //      (tl_flash_end !=0 )
        if(tl_flash_end){
            //     
            if(globalTimer > tl_flash_end){
                use_main_values = !use_main_values;             // !use_main_values -      ))
                setPorts(current_signal, use_main_values);      //      
                setPeriods(current_signal, false);              //     ,   
            }
        }

        //         -    operating_std     - --
        if(tl_signal_end){
            //       (use_main_values -       -  )
            if((globalTimer > tl_signal_end)  && use_main_values){
                current_signal ++;                          //   
                current_signal &= LIGHT_NUM_STD_MASK;       //    3-,        0  7
                use_main_values = true;                     //  -    
                setPorts(current_signal, use_main_values);  //        
                setPeriods(current_signal, true);           //       
            }
        }

        sleep_cpu();    //      -   .
    }
}

    //   
 void setPorts(uint8_t num, bool use_main_values){
    uint8_t val;
    DDRB = 0; PORTB = 0;
    //    () - ddr_val_0, else = ddr_val_1
//  val = (use_main_values) ? pgm_read_byte_near(&(traffic_signals[num].ddr_val_0))
//                          : pgm_read_byte_near(&(traffic_signals[num].ddr_val_1));

    //   ,  , ,  ,   ,   14 (!!!)   .
    val = pgm_read_byte_near(&(traffic_signals[num].ddr_val_0)+( (use_main_values) ? 0 : 2) ); 
    val &= ~_BV(BUTTON);    //     - 
    DDRB = val;             //    

    val = (use_main_values) ? pgm_read_byte_near(&(traffic_signals[num].port_val_0)) 
                            : pgm_read_byte_near(&(traffic_signals[num].port_val_1));
    val|= _BV(BUTTON);  //     -  -    
    PORTB = val;        //      
}

 //     ( 
void setPeriods(uint8_t num, bool set_both_flash_and_signal){
//  
    tl_flash_end = pgm_read_word_near (&(traffic_signals[num].flash_period));   //  
    tl_flash_end = (tl_flash_end)? tl_flash_end + globalTimer : 0;  //    -      
    //if(tl_flash_end){         tl_flash_end += globalTimer;    } <-     8  

    //     -    
    if(set_both_flash_and_signal){
        tl_signal_end = pgm_read_word_near(&(traffic_signals[num].signal_period));  
        tl_signal_end = (tl_signal_end)? tl_signal_end + globalTimer : 0;           //     ,    
    }
}

//Program size: 610 bytes (used 60% of a 1 024 byte maximum) (0,58 secs)
//Minimum Memory Usage: 7 bytes (11% of a 64 byte maximum)
      
      







, . — btn_cnt ( ), ( ) .







#define PERIOD_PRESS_BUTTON_SHORT   QT_SECOND           //      -  
#define PERIOD_PRESS_BUTTON_LONG    QT_SECOND*6         //      - /
uint8_t scan_button_cnt;    //    
        //  
        if(BUTTON_ON){
            if(scan_button_cnt<USHRT_MAX){
                scan_button_cnt++;      //   1/37     
            }
            if(scan_button_cnt > PERIOD_PRESS_BUTTON_SHORT){
                    // ,     
            }
            if(scan_button_cnt > PERIOD_PRESS_BUTTON_LONG){
                    //     
            }
        }

      
      





— .













SLEEP_MODE_IDLE ( CPU), PwrDown SLEEP_MODE_PWR_DOWN — watchdog INT0, , — INT0.













. 7.Power management and sleep modes ATtiny13 , 5-10 , .







8- , — 2 .







//  uint8_t f_button_state_flags;       //        

//      MODES:  wakeup 11 -> work 00 -> tosleep 01 -> pwrdown 11 -> wakeup 11
#define MODE_LBIT 0
#define MODE_HBIT 1
#define FORCE_SET_NEW_SIGNAL_BIT        2   //             current_signal
//    3
#define LIGHT_SIGNAL_ALT_MODE_BIT       4   // =0 (--)  =1 ( )   
#define USE_FIRST_VALUES_LIGHT_BIT      5   //     -  lightSignalization  
#define SHORT_PRESS_FLAG_BIT    6   // , 1       
#define LONG_PRESS_FLAG_BIT     7 // , 1       
      
      





, — , — CPU . , if-.







#include <limits.h>         // USHRT_MAX
#include <avr/io.h>         //     IDE
#include <avr/sleep.h>      // ,     
#include <avr/interrupt.h>  //   
#include <avr/pgmspace.h>   //    

#ifdef GIMSK    //  ATtiny13 -       
#define F_CPU 9600000UL     //      ,   
#define ONE_SECOND  37      //     1 
#define QT_SECOND   9       //  
// GIMSK &= ~_BV(INT0); -   INT0  
#define DISABLE_EXTERNAL_INT0   GIMSK &= ~(_BV(INT0)); GIFR  &= ~(_BV(INTF0))   //EIMSK/EIFR  
//GIMSK |= _BV(INT0) -   INT0
#define ENABLE_EXTERNAL_INT0    GIMSK |= _BV(INT0)  ; GIFR  &= ~(_BV(INTF0))
#else           // 328 -   
#define F_CPU 16000000UL
#define ONE_SECOND  64      //     1  - .   
#define QT_SECOND   16      //  
// 328 INT0 -  PD2...     ,       (,  ),            
#define DISABLE_EXTERNAL_INT0   EIMSK &= ~(_BV(INT0)); EIFR  &= ~(_BV(INTF0)) 
// ,   -  EICRA - ISC00-ISC01 == 00, lo level, EIMSK - INT0, EIFR-INTF0  
#define ENABLE_EXTERNAL_INT0    EIMSK |= _BV(INT0)  ; EIFR  &= ~(_BV(INTF0))
#endif

#define MAX_GLOBAL_TIMER_VALUE  (USHRT_MAX / 2)     // uint16_t globalTimer -   . 65535 /2 
//     ,  MAX_GLOBAL_TIMER_VALUE - 1
#define PERIOD_PRESS_BUTTON_SHORT   QT_SECOND/2         //      ( - ) -  
#define PERIOD_PRESS_BUTTON_LONG    QT_SECOND*4         //      - /
#define PERIOD_FLASH_GREEN          QT_SECOND           //     ( ) -    
#define PERIOD_FLASH_YELLOW         ONE_SECOND * 1      //     -    - 

                                            //  --- 
#define PERIOD_0        ONE_SECOND * 5      // R G R G  0.  ---   (5 )
#define PERIOD_1        ONE_SECOND * 3      //R g R g   1.  ---   (3 )     
#define PERIOD_2        ONE_SECOND * 1      //R Y R Y   2.  ---  (1 )
#define PERIOD_3        ONE_SECOND * 2      //RY Y RY Y 3. + ---  (2 ) 
#define PERIOD_4        ONE_SECOND * 7      // G R G R  4.  ---   (7 )
#define PERIOD_5        ONE_SECOND * 3      //g R g R   5.   --- (3 )
#define PERIOD_6        ONE_SECOND * 1      //Y R Y R   6.  ---  (1 )
#define PERIOD_7        ONE_SECOND * 2      //Y RY Y RY 7.  --- + (2 )

//  /  .     -     
typedef struct{
    const uint8_t ddr_val_0;    // DDRB value    
    const uint8_t port_val_0;   // PORTB value  
    const uint8_t ddr_val_1;    // DDRB value    
    const uint8_t port_val_1;   // PORTB value
    const uint16_t flash_period;    // period of flashing -   _val_1  _val_0 ( =0,  )
    const uint16_t signal_period;   // period of this lighting state ( =0,       )
}lightSignalization;            //   , _0  _1 -   , flash_long -   

//    (PINS === 0 0 0 g r y0 btt y1):
 //     ""     
#define BUTTON_PIN  PB1     // ,   INT0. ,   ,  = LOW
#define RED_PIN     PB3     // OUT: 1 - "-" , 0 - "-" , IN -  , ,  (!) 
#define YELLOW0_PIN PB2     // OUT: 1 -  "-" 
#define YELLOW1_PIN PB0     // OUT: 1 -  "-" 
#define GREEN_PIN   PB4     // OUT: 1 - "-" , 0 - "-" , IN -  , ,  (!) 

#define BUTTON_ON  !(PINB & _BV(BUTTON_PIN))    //( (PINB & _BV(BUTTON)) == 0)  //  " "
#define BUTTON_OFF  (PINB & _BV(BUTTON_PIN))    // ~(PINB & _BV(BUTTON)) -\\- " "

#define RED     _BV(RED_PIN)            // _BV -     (), 1<<VALUE
#define YELL0   _BV(YELLOW0_PIN)        //    -
#define YELL1   _BV(YELLOW1_PIN)
#define GREEN   _BV(GREEN_PIN)          //    - (  0 -   -)  DDR=1

//      lightSignalization traffic_signals[]
#define LIGHT_NUM_YELLOW_FLASH  8       //       ( ) -  - flash yellows lights
#define LIGHT_NUM_STD_START     0       //        (--)
#define LIGHT_NUM_LIGHTS_OFF    9       //      -   - traffic lights off
#define LIGHT_NUM_START_SHOW    10      //         
#define LIGHT_NUM_ERR           11      //   -     

#define MASK_LIGHT_NUM_STD      7       // ___++ &= LIGHT_NUM_STD_MASK -    0  7   

//....................................  
// 
const lightSignalization traffic_signals[] PROGMEM= {   //   ,  ,   -, PINS === 0 0 0 g r y0 btt y1
 // {DDRB0, PORTB0,   DDRB_flashing, PORTB_flasinf (if flashing),   continuous of half-period flashing,   continuous id mode running}
    {RED|GREEN, RED,   0, 0,   0, PERIOD_0},                    // R G R G
    {RED, RED,  RED|GREEN, RED,   QT_SECOND, PERIOD_1},         // R g R g - flash east green
    {RED|YELL1, RED|YELL1,   0, 0,   0, PERIOD_2 },             // R Y1 R Y1
    {RED|YELL0|YELL1, RED|YELL0|YELL1,  0, 0,   0, PERIOD_3 },  // RY0 Y1 RY0 Y1
    {RED|GREEN, GREEN,   0, 0,   0, PERIOD_4},                  // G R G R
    {RED|GREEN, GREEN,   RED, 0,    QT_SECOND, PERIOD_5 },      // g R g R - flash nord green
    {RED|YELL0, YELL0,   0, 0,   0, PERIOD_6},                  // Y0 R Y0 R
    {RED|YELL0|YELL1,  YELL0|YELL1,   0, 0,   0, PERIOD_7  },   // Y0 RY1 Y0 RY1

    {YELL0|YELL1, YELL0|YELL1,   YELL0|YELL1, 0,  ONE_SECOND, 0},   // y0 y1 y0 y1 - flash yellows lights 
    {0, 0,   0, 0,   0, 0},             //  traffic lights off, 
    {RED|GREEN|YELL0, RED|YELL0,   RED|GREEN|YELL1, GREEN|YELL1,   1, PERIOD_2},        //  PERIOD_2  -      ,     

    {YELL0|GREEN, YELL0,   YELL1|GREEN, YELL1|GREEN,  1, 0}     //  -     
};

volatile uint16_t  globalTimer; //      64   
uint8_t scan_button_cnt;        //      
uint16_t tl_flash_end;          // 2       ( !0), 
uint16_t tl_signal_end;         // 2            ( !0) 
uint8_t f_button_state_flags;   // 1,        
// , 8    

#pragma region bits_of_f_button_state_flags 
    //      MODES:  wakeup 11 -> work 00 -> tosleep 01 -> pwrdown 11 -> wakeup 11
#define MODE_LBIT 0
#define MODE_HBIT 1
#define MODE_VALUE          ( f_button_state_flags & 3 )    //  -   MODE_
#define SET_MODE_WORK       f_button_state_flags &= ~(_BV(MODE_HBIT) );  f_button_state_flags &= ~(_BV(MODE_LBIT) );// 00 - work
//  f_button_state_flags &= ~( _BV(MODE_HBIT) | _BV(MODE_LBIT) ) -    ,  
#define MODE_WORK_VALUE     0
#define SET_MODE_TOSLEEP    f_button_state_flags &= ~(_BV(MODE_HBIT)); f_button_state_flags |= _BV(MODE_LBIT)   // 01 - tosleep
#define MODE_TOSLEEP_VALUE  1
#define SET_MODE_PWRDOWN    f_button_state_flags |= _BV(MODE_HBIT); f_button_state_flags &= ~(_BV(MODE_LBIT))   // 10 - pwrdown 
#define MODE_PWRDOWN_VALUE  2
#define SET_MODE_WAKEUP     f_button_state_flags |= _BV(MODE_HBIT); f_button_state_flags |= _BV(MODE_LBIT)      // 11 - wakeup  
#define MODE_WAKEUP_VALUE   3

#define FORCE_SET_NEW_SIGNAL_BIT        2   //             current_signal
#define IF_FORCE_SET_SIGNAL_FLAG        ( f_button_state_flags & _BV(FORCE_SET_NEW_SIGNAL_BIT) )    // IF_ -    
#define SET_FORCE_SET_SIGNAL_FLAG       f_button_state_flags |=  _BV(FORCE_SET_NEW_SIGNAL_BIT)      // SET_ -    1
#define RES_FORCE_SET_SIGNAL_FLAG       f_button_state_flags &= ~( _BV(FORCE_SET_NEW_SIGNAL_BIT) )  // RES_ -    0

//  3   

#define LIGHT_SIGNAL_ALT_MODE_BIT       4   // =0 (--)  =1 ( )   
#define IF_LIGHT_SIGNAL_ALT_MODE_FLAG   ( f_button_state_flags & _BV(LIGHT_SIGNAL_ALT_MODE_BIT) )   //1( )  0(--)   ?
#define SET_LIGHT_SIGNAL_ALT_MODE_FLAG  f_button_state_flags |=  _BV(LIGHT_SIGNAL_ALT_MODE_BIT)
#define RES_LIGHT_SIGNAL_ALT_MODE_FLAG  f_button_state_flags &= ~( _BV(LIGHT_SIGNAL_ALT_MODE_BIT) )
#define FLIP_LIGHT_SIGNAL_ALT_MODE_FLAG f_button_state_flags ^= _BV(LIGHT_SIGNAL_ALT_MODE_BIT)

#define USE_FIRST_VALUES_LIGHT_BIT      5   //     -  lightSignalization  
#define IF_USE_FIRST_VALUES_LIGHT_FLAG  (f_button_state_flags & _BV(USE_FIRST_VALUES_LIGHT_BIT)) // lightSignalization._val_0 (1)  lightSignalization._val_1 (0)? -  
#define SET_USE_FIRST_VALUES_LIGHT_FLAG     f_button_state_flags |= _BV(USE_FIRST_VALUES_LIGHT_BIT)
#define RES_USE_FIRST_VALUES_LIGHT_FLAG     f_button_state_flags &= ~( _BV(USE_FIRST_VALUES_LIGHT_BIT))
#define FLIP_USE_FIRST_VALUES_LIGHT_FLAG    f_button_state_flags ^= _BV(USE_FIRST_VALUES_LIGHT_BIT)     //  

#define SHORT_PRESS_FLAG_BIT    6   // , 1       
#define IF_SHORT_PRESS_FLAG     ( f_button_state_flags & _BV(SHORT_PRESS_FLAG_BIT) )        // -   == 1
#define SET_SHORT_PRESS_FLAG    f_button_state_flags |= _BV(SHORT_PRESS_FLAG_BIT)
#define RES_SHORT_PRESS_FLAG    f_button_state_flags &= ~(_BV(SHORT_PRESS_FLAG_BIT))

#define LONG_PRESS_FLAG_BIT     7 // , 1       
#define IF_LONG_PRESS_FLAG      ( f_button_state_flags & _BV(LONG_PRESS_FLAG_BIT) )     // -   == 1
#define SET_LONG_PRESS_FLAG     f_button_state_flags |= _BV(LONG_PRESS_FLAG_BIT)
#define RES_LONG_PRESS_FLAG     f_button_state_flags &= ~(_BV(LONG_PRESS_FLAG_BIT))
#pragma endregion

//....................................  
void setPeriods(uint8_t num, bool set_both_flash_and_signal);   //  tl_flash_end, tl_signal_end
void setPorts(uint8_t num, bool use_main_values);               //    
void inline init_timer_clock(){     //     
#ifdef GIMSK    //  ATtiny13 - 
    TCCR0B = _BV(CS02) | _BV(CS00); //  0 - clock frequency / 1024
    TIMSK0 |= _BV(TOIE0);           //      overflow interrupt
#else           //   , 328/16
    // 100 - prescaler 64; Foverflow = 16M/64*256 ~=976.56Hz,
    TCCR2B = (1<<CS22) | (1<<CS21) | (1<<CS20) ;  // 111 - CLK/1024, 16M/1024*254 - 1/64 
    TIMSK2 |=(1<<TOIE0);  // interrupt ovfl enable
    //Serial.begin(115200);
#endif
}

//....................................  
//
//  -  -    globalTimer  1/37 
#ifdef GIMSK    //  ATtiny13
ISR(TIM0_OVF_vect){
    globalTimer++;  //       . ,   while(1)   .
}
#else
//   0 -     , -   - -     2
ISR(TIMER2_OVF_vect){
    globalTimer++;
}
#endif
//   -    (,  ,    0)
ISR(INT0_vect){
    DISABLE_EXTERNAL_INT0;
    SET_MODE_WAKEUP;        //      POWER DOWN
    globalTimer = 0;        //  -  
    scan_button_cnt = 0;    //   
    RES_SHORT_PRESS_FLAG;   //
    RES_LONG_PRESS_FLAG;    //  
}

/*
//   - 
void inline dbg(){
    DDRB |= YELL0; PORTB ^= YELL0;
}
*/

//....................................  
//
int main() {
    uint8_t current_signal;             // 1    ,   traffic_signals

#pragma region Initialisation&setup
    //     "  -". 
    set_sleep_mode(SLEEP_MODE_IDLE);    //   - .
    sleep_enable();             //    

    init_timer_clock();         //     

    globalTimer = 0;            //  -  
    SET_MODE_WORK;              //    
    SET_USE_FIRST_VALUES_LIGHT_FLAG;    //  
    scan_button_cnt = 0;        //   

    //       
    current_signal = LIGHT_NUM_START_SHOW;  //     -   /
    SET_FORCE_SET_SIGNAL_FLAG;              //    current_signal

    sei();      //    

#pragma endregion
    while(1){

#pragma region TimerOVF
        //   ? 
        if(globalTimer > MAX_GLOBAL_TIMER_VALUE){
            globalTimer -= MAX_GLOBAL_TIMER_VALUE;          //   
            // 
            if(tl_flash_end){
                tl_flash_end -= MAX_GLOBAL_TIMER_VALUE;     //   ,  
            }
            if(tl_signal_end){
                tl_signal_end -= MAX_GLOBAL_TIMER_VALUE;    // //   ,  
            }
            // setPeriods(currentMode, false); //   12  ,  tl_.._end   ,     
        }
#pragma endregion

#pragma region ButtonState
        //  
        if(BUTTON_ON){
            if(scan_button_cnt < USHRT_MAX){
                scan_button_cnt++;              //   1/37     
            }
            //   -  ,    
            if(scan_button_cnt > PERIOD_PRESS_BUTTON_SHORT){
                SET_SHORT_PRESS_FLAG;       // ,     , 
            }
            if(scan_button_cnt > PERIOD_PRESS_BUTTON_LONG){
                SET_LONG_PRESS_FLAG;        //     
            }
        }
#pragma endregion
#pragma region LightWorkLogic
        //      (tl_flash_end !=0 )
        if(tl_flash_end){
            //     
            if(globalTimer > tl_flash_end){
                FLIP_USE_FIRST_VALUES_LIGHT_FLAG;               // !use_main_values -      ))
                setPorts(current_signal, IF_USE_FIRST_VALUES_LIGHT_FLAG);       //      
                setPeriods(current_signal, false);          //     ,   
            }
        }

        //         
        // -    operating_std     - -- 
        //    ,   +1   7
        if(tl_signal_end){
            //       (use_main_values -       -  )
            if((globalTimer > tl_signal_end)  && IF_USE_FIRST_VALUES_LIGHT_FLAG){
                current_signal ++;                          //   
                current_signal &= MASK_LIGHT_NUM_STD;       //    3-,        0  7
                SET_FORCE_SET_SIGNAL_FLAG;      //    current_signal
            }
        }
#pragma endregion

#pragma region MODE_VALUELogic
        //   , 2  f_button_state_flags
        //? MODE_VALUE === pwrdown -> wakeup -> work -> tosleep -> pwrdown
        switch (MODE_VALUE){
        case (MODE_WAKEUP_VALUE):
            set_sleep_mode(SLEEP_MODE_IDLE);        //  !
            //   ,       - IF_BUTTON_LONG_FLAG
            if(IF_LONG_PRESS_FLAG){
                //      ?   !
                if(current_signal == LIGHT_NUM_LIGHTS_OFF){
                    //          ? LIGHT_NUM_ERR
                    current_signal = (IF_LIGHT_SIGNAL_ALT_MODE_FLAG) ? LIGHT_NUM_YELLOW_FLASH : LIGHT_NUM_STD_START;
                    SET_FORCE_SET_SIGNAL_FLAG;      //    current_signal
                }
            }
            //,  ...
            if(BUTTON_OFF){
                //      ,   
                if(IF_LONG_PRESS_FLAG){
                    SET_MODE_WORK;
                }else{  
                    //  , ,   ,  
                    SET_MODE_PWRDOWN;   //        
                }
                scan_button_cnt = 0;    //       
                RES_SHORT_PRESS_FLAG;   //   , 
                RES_LONG_PRESS_FLAG;
            }
            break;

        case (MODE_WORK_VALUE):
            //  ?
            if(scan_button_cnt > 0){
                //   ?
                if(IF_LONG_PRESS_FLAG){
                    current_signal = LIGHT_NUM_LIGHTS_OFF;      //  
                    SET_FORCE_SET_SIGNAL_FLAG;                  //   -   " "
                    SET_MODE_TOSLEEP;                           //   !
                }
                // ? 
                if(BUTTON_OFF){
                    //     ?
                    if(IF_SHORT_PRESS_FLAG){
                        FLIP_LIGHT_SIGNAL_ALT_MODE_FLAG;    //     
                        current_signal = (IF_LIGHT_SIGNAL_ALT_MODE_FLAG) ? LIGHT_NUM_YELLOW_FLASH : LIGHT_NUM_STD_START; //    . 
                        SET_FORCE_SET_SIGNAL_FLAG;          //      current_signal
                    }
                    scan_button_cnt=0;
                    RES_SHORT_PRESS_FLAG; //    
                    RES_LONG_PRESS_FLAG;
                }
            }
            break;

        case (MODE_TOSLEEP_VALUE):
            //    -    .
            if(BUTTON_OFF){
                SET_MODE_PWRDOWN;       //    
            }
            break;

        case (MODE_PWRDOWN_VALUE):
            // !  , !  ?
            if(BUTTON_ON){
                set_sleep_mode(SLEEP_MODE_IDLE);
                SET_MODE_WAKEUP;
            }else{  
                //  ?  .
                scan_button_cnt = 0;
                RES_LONG_PRESS_FLAG;
                RES_SHORT_PRESS_FLAG;
                current_signal = LIGHT_NUM_LIGHTS_OFF;      // 
                SET_FORCE_SET_SIGNAL_FLAG;
                set_sleep_mode(SLEEP_MODE_PWR_DOWN);    //    -   while(1)
                ENABLE_EXTERNAL_INT0;                   //     
            }
            break;

        default:
            //!       -    .  -      
            current_signal = LIGHT_NUM_ERR;
            SET_FORCE_SET_SIGNAL_FLAG;
            //setPorts(current_signal,true);
            //setPeriods(current_signal,true);
            break;
        }
#pragma endregion

        //   ,      - ?
        if(IF_FORCE_SET_SIGNAL_FLAG){       //       current_signal
            RES_FORCE_SET_SIGNAL_FLAG;      //  
            SET_USE_FIRST_VALUES_LIGHT_FLAG;    //   -   0-   -
            setPorts(current_signal, IF_USE_FIRST_VALUES_LIGHT_FLAG);   //      #current_signal  
            setPeriods(current_signal, true);
        }

        //    1/37 . , ,  .
        sleep_cpu();    //       -   .
        }
}

//.................................... 
//
//    
 void setPorts(uint8_t num, bool  use_main_values){
    uint8_t val;
    DDRB = 0; PORTB = 0;
    //    () - ddr_val_0, else = ddr_val_1
//  val = (use_main_values) ? pgm_read_byte_near(&(traffic_signals[num].ddr_val_0))
//                          : pgm_read_byte_near(&(traffic_signals[num].ddr_val_1));

    //   ,    ,  ,   ,   14 (!!!)   .
    val = pgm_read_byte_near(&(traffic_signals[num].ddr_val_0)+( (use_main_values) ? 0 : sizeof(uint8_t)*2 ) ); 

    val &= ~_BV(BUTTON_PIN);    //    ,    - 
    DDRB = val;                 //    

    val = (use_main_values) ? pgm_read_byte_near(&(traffic_signals[num].port_val_0)) 
                            : pgm_read_byte_near(&(traffic_signals[num].port_val_1));
    val|= _BV(BUTTON_PIN);  //     -  -    
    PORTB = val;        //      
}

 //     (    )
void setPeriods(uint8_t num, bool set_both_flash_and_signal){
//  
    tl_flash_end = pgm_read_word_near (&(traffic_signals[num].flash_period));   //  
    tl_flash_end = (tl_flash_end)? tl_flash_end + globalTimer : 0;  //    -      
    //if(tl_flash_end){         tl_flash_end += globalTimer;    } <-     8  

    //     -    
    if(set_both_flash_and_signal){
        tl_signal_end = pgm_read_word_near(&(traffic_signals[num].signal_period));  
        tl_signal_end = (tl_signal_end)? tl_signal_end + globalTimer : 0;           //     ,    
    }
}
//Program size: 976 bytes (used 95% of a 1 024 byte maximum) (0,83 secs)
//Minimum Memory Usage: 8 bytes (13% of a 64 byte maximum)
      
      





Program size: 976 bytes (used 95% of a 1 024 byte maximum) (0,83 secs)

Minimum Memory Usage: 8 bytes (13% of a 64 byte maximum)







.







ATtiny13 .







-



( ?) . — . , , , . , , .







,



DipTrace «» «PCB Layout», . , .













— .













, , .







( , 80- ).













CD .













, , , .













— .







: , .







, , . — , .















— . - - "Craft&Clay" 50- 70. , .













.













15 130 .













— .



















— .













— .













.













4 , 2-3 ,

, .













. , , , " ".













, .













KSP. — 4 LED 5 .













, , DC-DC 0.9-5 , .













. , , .















, , , .













ISP 10- .















, , , - . , , " ". 1.5 , — . , .







, , %/ ,
CR1212 18 1 0.250
CR1620 68 1 0.950
CR2032 210 1 3
NiCD AAA 350 20 98
NiMH AAA 900 30 375
NiCd AA 1000 20 270
Alkaline AAA 1250 2 35
NiMH AA 2400 30 1000
Alkaline AA 2890 2 80
Li-Ion 4400 10 600


, . , , (2/100)2890/(2430) = 80 . , 2 , 32 ATtiny13.







: , GPIO, . — , ( 4 14 ""), , 40 .







, — . , . , : 5 DC-DC , , DC-DC 1.5 -> 5 . , - +-20%, .













, "" 4-5 (5 ) , , 25 (1.5 ),













.. 2890 116 , . ATtiny13 POWER DOWN . , — . 20-50 , , Hi-Z, 1 . , DC-DC .







2 5 . : .







,



, :









.







: " ", , 8 , , «» .







.











Github, MIT.








All Articles