| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373 |
- /*
- HelloWorld.ino
- Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
- Copyright (c) 2016, olikraus@gmail.com
- All rights reserved.
- Redistribution and use in source and binary forms, with or without modification,
- are permitted provided that the following conditions are met:
- * Redistributions of source code must retain the above copyright notice, this list
- of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright notice, this
- list of conditions and the following disclaimer in the documentation and/or other
- materials provided with the distribution.
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
- CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
- #include <Arduino.h>
- #include <U8g2lib.h>
- uint8_t light_to_pin[4] = { 11, 10, 9, 8 };
- uint8_t switch_to_pin[4] = { 7, 6, 5, 4 };
- #define SWITCH_ON 0
- #define SWITCH_OFF 1
- #define LIGHT_ON 1
- #define LIGHT_OFF 0
- #define TIMEOUT 3000
- uint8_t switch_status[4];
- #define DEBOUNCE_CNT 3
- uint8_t switch_debounce[4];
- uint8_t is_switch_changed;
- uint8_t last_switch_on_cnt; // number of "on" switches before the last change
- uint8_t switch_on_cnt; // current number of "on" switches
- uint8_t max_on_cnt; // last number max number of "on" switches
- // max_on_cnt==1: max_on_cnt_pos1 --> on switch
- // max_on_cnt==2: max_on_cnt_pos1/2 --> on switch
- // max_on_cnt==3: max_on_cnt_pos1 --> off switch
- // max_on_cnt==4: max_on_cnt_pos1 --> last switch which was turned off
- int8_t max_on_cnt_pos1 = -1;
- int8_t max_on_cnt_pos2 = -1;
- int8_t user_pos1;
- int8_t user_pos2;
- int8_t max_on_cnt_npos1 = -1;
- int8_t max_on_cnt_npos2 = -1;
- uint32_t switch_changed_millis;
- uint8_t map_switch_to_light[4];
- #define STATE_WAIT 0
- #define STATE_DELAYED_SWAP_WAIT 1
- uint8_t state = STATE_WAIT;
- U8G2_SSD1306_128X32_UNIVISION_F_HW_I2C u8g2(U8G2_R3, /* reset=*/ U8X8_PIN_NONE);
- U8G2LOG u8g2log;
- uint8_t u8log_buffer[6*14];
- void init_switch(void)
- {
- uint8_t i;
- for( i = 0; i < 4; i++ )
- {
- pinMode(switch_to_pin[i], INPUT_PULLUP);
- switch_debounce[i] = 0;
- switch_status[i] = 2;
- map_switch_to_light[i] = i;
- }
- }
- void read_switch_status(void)
- {
- uint8_t i, v, on_cnt;
- int8_t pos1, pos2, npos1;
- for( i = 0; i < 4; i++ )
- {
- v = digitalRead(switch_to_pin[i]);
- if ( switch_debounce[i] > 0 )
- {
- if ( switch_status[i] == v )
- {
- switch_debounce[i] = 0; // do nothing, wait for other values
- }
- else
- {
- switch_debounce[i]--;
- if ( switch_debounce[i] == 0 )
- {
- switch_status[i] = v; // new value detected
- is_switch_changed = 1;
- switch_changed_millis = millis();
- break; // break out of the loop, so that we detect only one change at a time
- }
- }
- }
- else if ( switch_status[i] != v )
- {
- switch_debounce[i] = DEBOUNCE_CNT; // start debounce
- }
- }
-
- on_cnt = 0;
- pos1 = -1;
- pos2 = -1;
- for( i = 0; i < 4; i++ )
- {
- if ( switch_status[i] == SWITCH_ON )
- {
- on_cnt++;
- if ( pos1 < 0 )
- pos1 = i;
- else
- pos2 = i;
- }
- else
- {
- npos1 = i;
- }
- }
-
- if ( switch_on_cnt != on_cnt )
- {
- last_switch_on_cnt = switch_on_cnt;
- switch_on_cnt = on_cnt;
- if ( last_switch_on_cnt < switch_on_cnt )
- {
- max_on_cnt = on_cnt;
- if ( max_on_cnt == 1 )
- {
- max_on_cnt_pos1 = pos1;
- max_on_cnt_pos2 = -1;
- }
- else if ( max_on_cnt == 2 )
- {
- max_on_cnt_pos1 = pos1;
- max_on_cnt_pos2 = pos2;
- }
- else if ( max_on_cnt == 3 )
- {
- max_on_cnt_pos1 = npos1;
- max_on_cnt_pos2 = -1;
- }
- else if ( max_on_cnt == 4 )
- {
- max_on_cnt_pos1 = -1;
- max_on_cnt_pos2 = -1;
- }
- else
- {
- max_on_cnt_pos1 = -1;
- max_on_cnt_pos2 = -1;
- }
- }
- else if ( last_switch_on_cnt > switch_on_cnt )
- {
- if ( max_on_cnt == 4 )
- {
- if ( switch_on_cnt == 1 )
- {
- max_on_cnt_pos1 = pos1;
- max_on_cnt_pos2 = -1;
- }
- }
- }
-
- }
-
- }
- void print_switch_status(void)
- {
- uint8_t i;
-
- u8g2log.print(last_switch_on_cnt);
- u8g2log.print(">");
- u8g2log.print(switch_on_cnt);
- u8g2log.print("/");
- u8g2log.print(max_on_cnt);
- u8g2log.print("\n");
-
- u8g2log.print(max_on_cnt_pos1);
- u8g2log.print("/");
- u8g2log.print(max_on_cnt_pos2);
- u8g2log.print("\n");
-
- for( i = 0; i < 4; i++ )
- u8g2log.print(switch_status[i] == 0 ? "*" : ".");
- u8g2log.print("\n");
- }
- void init_light(void)
- {
- uint8_t i;
- for( i = 0; i < 4; i++ )
- {
- digitalWrite(light_to_pin[i], 1);
- pinMode(light_to_pin[i], OUTPUT);
- digitalWrite(light_to_pin[i], 1);
- }
- }
- void write_switch_to_light(void)
- {
- uint8_t i;
- for( i = 0; i < 4; i++ )
- {
- if ( switch_status[i] == SWITCH_ON )
- digitalWrite(light_to_pin[map_switch_to_light[i]], LIGHT_ON);
- else
- digitalWrite(light_to_pin[map_switch_to_light[i]], LIGHT_OFF);
- }
- }
- /*==============================================*/
- void next_state(void)
- {
- read_switch_status();
-
- switch(state)
- {
- case STATE_WAIT:
- if ( switch_changed_millis+TIMEOUT < millis() )
- {
- if ( switch_on_cnt == 0 )
- {
- switch_changed_millis = millis();
- if ( max_on_cnt == 1 ) // main command "1 light max"
- {
- if ( max_on_cnt_pos1 == 0 ) // sub cmd reset
- {
- uint8_t i;
- for( i = 0; i < 4; i++ )
- {
- map_switch_to_light[i] = i;
- }
- u8g2log.print(F("reset\n"));
- }
- else if ( max_on_cnt_pos1 == 1 ) // sub cmd user choice
- {
- state = STATE_DELAYED_SWAP_WAIT;
- user_pos1 = -1;
- user_pos2 = -1;
-
- u8g2log.print(F("user\n"));
- }
- }
- else if ( max_on_cnt == 2 ) // main command "2 light max"
- {
- // swap two pins
- uint8_t tmp;
- tmp = map_switch_to_light[max_on_cnt_pos1];
- map_switch_to_light[max_on_cnt_pos1] = map_switch_to_light[max_on_cnt_pos2];
- map_switch_to_light[max_on_cnt_pos2] = tmp;
- u8g2log.print(F("swap\n"));
- }
- else
- {
- u8g2log.print("t-out\n");
- }
- max_on_cnt = 0; // ensure, that the command is not executed again
- }
- }
- break;
- case STATE_DELAYED_SWAP_WAIT: // user choice
- {
- uint8_t i, j;
- for( i = 0; i < 4; i++ )
- {
- if ( user_pos1 != i && switch_status[i] == SWITCH_ON )
- {
- if ( user_pos1 < 0 )
- user_pos1 = i;
- else
- {
- uint8_t tmp;
-
- user_pos2 = i;
- tmp = 1<<user_pos1;
- tmp |= 1<<user_pos2;
- max_on_cnt_npos1 = -1;
- max_on_cnt_npos2 = -1;
-
- for( j = 0; j < 4; j++ )
- {
- if ( ( tmp & (1<<j) ) == 0 )
- {
- if ( max_on_cnt_npos1 < 0 )
- max_on_cnt_npos1 = j;
- else
- max_on_cnt_npos2 = j;
- }
- }
-
-
- tmp = map_switch_to_light[max_on_cnt_npos1];
- map_switch_to_light[max_on_cnt_npos1] = map_switch_to_light[max_on_cnt_npos2];
- map_switch_to_light[max_on_cnt_npos2] = tmp;
-
- u8g2log.print(F("swap2\n"));
- u8g2log.print(max_on_cnt_npos1);
- u8g2log.print(F("<>"));
- u8g2log.print(max_on_cnt_npos2);
- u8g2log.print(F("\n"));
-
- state = STATE_WAIT;
- switch_changed_millis = millis();
- }
- }
- }
-
- }
- break;
- default:
- state = STATE_WAIT;
- break;
- }
-
- if ( is_switch_changed != 0 )
- {
- print_switch_status();
- write_switch_to_light();
- is_switch_changed = 0;
- }
- }
- /*==============================================*/
- void setup(void)
- {
- u8g2.begin();
- //u8g2.setFont(u8g2_font_tom_thumb_4x6_mf); // set the font for the terminal window
-
- //u8g2.setFont(u8g2_font_lucasfont_alternate_tr);
- u8g2.setFont(u8g2_font_6x12_tr);
- u8g2log.begin(u8g2, 6, 14, u8log_buffer);
-
- init_switch();
- init_light();
- }
- void loop(void)
- {
- next_state();
- }
|