Overview
Smile Function Decoder for NMRA Lib.
Comment
dec/8/2018
Fix notifyDccReset processing.
1)Added initialization of gState_Fn variable.
//------------------------------------------------------------------
// Reset
//------------------------------------------------------------------
void notifyDccReset(uint8_t hardReset )
{
digitalWrite(O1,LOW);
digitalWrite(O2,LOW);
digitalWrite(O3,LOW);
digitalWrite(O4,LOW);
gState_F0 = 0; // ADD
gState_F1 = 0; // ADD
gState_F2 = 0; // ADD
gState_F3 = 0; // ADD
gState_F4 = 0; // ADD
gState_F5 = 0; // ADD
}
2)DCC reset pulse emulation added.
if (Speed > 64) {
doing_Resets_Flag = true;
notifyDccReset(0);
} else {
doing_Resets_Flag = false;
}
link
https://twitter.com/masashi_214
http://ayabu.blog.shinobi.jp/
http://dcc.client.jp/
http://www007.upp.so-net.ne.jp/nagoden/
// 20181208 Kenneth west TEST Program ADD
//
// DCC Function Decoder Rev 2 for DS-DCC decode
// By yaasan
// Based on Nicolas's sketch http://blog.nicolas.cx
// Inspired by Geoff Bunza and his 17 Function DCC Decoder & updated library
// http://dcc.client.jp
// http://ayabu.blog.shinobi.jp
// O1:F3 でON/OFF head sign
// O2:F0 でON/OFF head light
// O3:F1 でON/OFF tail light
// O4:F5 でON/OFF room light
#include "NmraDcc.h"
#include <avr/eeprom.h> //required by notifyCVRead() function if enabled below
bool doing_Resets_Flag = false; // True if we are simulating reset packets.
//FX効果
//Cmd,Time,Val,Frq
//I:初期状態,O:出力,S:スイープ,L:ループ,E:終了
unsigned char ptn1[2][3]={{'I',0,255},{'E',0,255}}; //10ms すぐ点灯
unsigned char ptn2[3][3]={{'I',0,5},{'S',100,255},{'E',0,255}}; //10ms もやっと点灯
unsigned char ptn3[4][3]={{'I',0,5},{'S',50,255},{'S',50,5},{'L',0,5}}; //10ms 三角波
unsigned char ptn4[6][3]={{'I',0,0},{'O',10,255},{'O',10,125},{'O',10,255},{'O',10,80},{'L',0,0}}; // ランダム
unsigned char ptn5[6][3]={{'I',0,0},{'S',50,255},{'S',50,0},{'S',50,128},{'S',50,0},{'L',0,0}};//マーズライト
unsigned char ptn6[4][3]={{'I',0,0},{'O',30,255},{'S',20,128},{'L',0,0}};//フラッシュライト
unsigned char ptn7[4][3]={{'I',0,0},{'O',20,255},{'O',80,0},{'L',0,0}}; //シングルパルスストロボ
unsigned char ptn8[6][3]={{'I',0,0},{'O',10,255},{'O',20,0},{'O',10,255},{'O',60,0},{'L',0,0}}; //ダブルパルスストロボ
unsigned char ptn9[6][3]={{'I',0,0},{'O',25,128},{'O',40,255},{'O',25,128},{'O',40,0},{'L',0,0}}; //ミディアムパルスストロボ
unsigned char ptn10[8][3]={{'I',0,0},{'O',1,255},{'O',1,0},{'O',1,255},{'O',30,0},{'O',10,50},{'O',100,255},{'E',0,0}}; //グロー管蛍光灯
unsigned char ptn11[9][3]={{'I',0,0},{'O',1,255},{'O',1,0},{'O',1,255},{'O',30,0},{'O',30,40},{'O',50,255},{'O',70,0},{'L',0,0}}; //グロー管蛍光灯切れそう
unsigned char (*ptn)[3];
//各種設定、宣言
#define DECODER_ADDRESS 3
#define DCC_ACK_PIN 0 // Atiny85 PB0(5pin) if defined enables the ACK pin functionality. Comment out to disable.
// // Atiny85 DCCin(7pin)
#define O1 0 // Atiny85 PB0(5pin) head sign light
#define O2 1 // Atiny85 PB1(6pin) analogwrite Head light
#define O3 3 // Atint85 PB3(2pin) tail light
#define O4 4 // Atiny85 PB4(3pin) analogwrite room light
#define MAX_PWMDUTY 255
#define MID_PWMDUTY 10
#define CV_VSTART 2
#define CV_ACCRATIO 3
#define CV_DECCRATIO 4
#define CV_F0_FORWARD 33
#define CV_F0_BACK 34
#define CV_F1 35
#define CV_F2 36
#define CV_F3 37
#define CV_F4 38
#define CV_F5 39
#define CV_F6 40
#define CV_F7 41
#define CV_F8 42
#define CV_F9 43
#define CV_F10 44
#define CV_F11 45
#define CV_F12 46
#define CV_49_F0_FORWARD_LIGHT 49
#define CV_DIMMING_SPEED 50
#define CV_DIMMING_LIGHT_QUANTITY 51
#define CV_ROOM_DIMMING 52
//ファンクションの変数
uint8_t fn_bit_f0 = 0;
uint8_t fn_bit_f1 = 0;
uint8_t fn_bit_f2 = 0;
uint8_t fn_bit_f3 = 0;
uint8_t fn_bit_f4 = 0;
uint8_t fn_bit_f5 = 0;
uint8_t fn_bit_f6 = 0;
uint8_t fn_bit_f7 = 0;
uint8_t fn_bit_f8 = 0;
uint8_t fn_bit_f9 = 0;
uint8_t fn_bit_f10 = 0;
uint8_t fn_bit_f11 = 0;
uint8_t fn_bit_f12 = 0;
uint8_t fn_bit_f13 = 0;
uint8_t fn_bit_f14 = 0;
uint8_t fn_bit_f15 = 0;
uint8_t fn_bit_f16 = 0;
uint8_t fn_bit_f17 = 0;
uint8_t fn_bit_f18 = 0;
uint8_t fn_bit_f19 = 0;
uint8_t fn_bit_f20 = 0;
uint8_t fn_bit_f21 = 0;
uint8_t fn_bit_f22 = 0;
uint8_t fn_bit_f23 = 0;
uint8_t fn_bit_f24 = 0;
uint8_t fn_bit_f25 = 0;
uint8_t fn_bit_f26 = 0;
uint8_t fn_bit_f27 = 0;
uint8_t fn_bit_f28 = 0;
//使用クラスの宣言
NmraDcc Dcc;
DCC_MSG Packet;
//Task Schedule
unsigned long gPreviousL5 = 0;
//進行方向
uint8_t gDirection = 128;
//Function State
uint8_t gState_F0 = 0;
uint8_t gState_F1 = 0;
uint8_t gState_F2 = 0;
uint8_t gState_F3 = 0;
uint8_t gState_F4 = 0;
uint8_t gState_F5 = 0;
uint8_t gState_F6 = 0;
uint8_t gState_F7 = 0;
uint8_t gState_F8 = 0;
uint8_t gState_F9 = 0;
uint8_t gState_F10 = 0;
uint8_t gState_F11 = 0;
uint8_t gState_F12 = 0;
//モータ制御関連の変数
uint32_t gSpeedRef = 1;
//CV related
uint8_t gCV1_SAddr = 3;
uint8_t gCVx_LAddr = 3;
uint8_t gCV49_fx = 20;
uint8_t gCV50_DimmingSpeed = 1;
uint8_t gCV51_DimmingLightQuantity = 10;
uint8_t gCV52_RoomDimming = 128;
//Internal variables and other.
#if defined(DCC_ACK_PIN)
const int DccAckPin = DCC_ACK_PIN ;
#endif
struct CVPair {
uint16_t CV;
uint8_t Value;
};
CVPair FactoryDefaultCVs [] = {
{CV_MULTIFUNCTION_PRIMARY_ADDRESS, DECODER_ADDRESS}, // CV01
{CV_ACCESSORY_DECODER_ADDRESS_MSB, 0}, // CV09 The LSB is set CV 1 in the libraries .h file, which is the regular address location, so by setting the MSB to 0 we tell the library to use the same address as the primary address. 0 DECODER_ADDRESS
{CV_MULTIFUNCTION_EXTENDED_ADDRESS_MSB, 0}, // CV17 XX in the XXYY address
{CV_MULTIFUNCTION_EXTENDED_ADDRESS_LSB, 0}, // CV18 YY in the XXYY address
{CV_29_CONFIG, 128 }, // CV29 Make sure this is 0 or else it will be random based on what is in the eeprom which could caue headaches
{CV_49_F0_FORWARD_LIGHT, 20}, // CV49 F0 Forward Light
{CV_DIMMING_SPEED, 1},
{CV_DIMMING_LIGHT_QUANTITY,10},
{CV_ROOM_DIMMING, 100},
};
void(* resetFunc) (void) = 0; //declare reset function at address 0
void LightMes( char,char );
void pulse(void);
uint8_t FactoryDefaultCVIndex = sizeof(FactoryDefaultCVs) / sizeof(CVPair);
void notifyDccReset(uint8_t hardReset );
//uint16_t limitSpeed(uint16_t inSpeed);
void notifyCVResetFactoryDefault()
{
//When anything is writen to CV8 reset to defaults.
resetCVToDefault();
//Serial.println("Resetting...");
delay(1000); //typical CV programming sends the same command multiple times - specially since we dont ACK. so ignore them by delaying
resetFunc();
};
//------------------------------------------------------------------
// Reset
//------------------------------------------------------------------
void notifyDccReset(uint8_t hardReset )
{
digitalWrite(O1,LOW);
digitalWrite(O2,LOW);
digitalWrite(O3,LOW);
digitalWrite(O4,LOW);
gState_F0 = 0; // ADD
gState_F1 = 0; // ADD
gState_F2 = 0; // ADD
gState_F3 = 0; // ADD
gState_F4 = 0; // ADD
gState_F5 = 0; // ADD
}
//------------------------------------------------------------------
// CVをデフォルトにリセット
// Serial.println("CVs being reset to factory defaults");
//------------------------------------------------------------------
void resetCVToDefault()
{
for (int j = 0; j < FactoryDefaultCVIndex; j++ ) {
Dcc.setCV( FactoryDefaultCVs[j].CV, FactoryDefaultCVs[j].Value);
}
};
extern void notifyCVChange( uint16_t CV, uint8_t Value) {
//CVが変更されたときのメッセージ
//Serial.print("CV ");
//Serial.print(CV);
//Serial.print(" Changed to ");
//Serial.println(Value, DEC);
};
//------------------------------------------------------------------
// CV Ack
//------------------------------------------------------------------
void notifyCVAck(void)
{
//Serial.println("notifyCVAck");
digitalWrite(O1,HIGH);
digitalWrite(O2,HIGH);
digitalWrite(O3,HIGH);
digitalWrite(O4,HIGH);
delay( 6 );
digitalWrite(O1,LOW);
digitalWrite(O2,LOW);
digitalWrite(O3,LOW);
digitalWrite(O4,LOW);
}
//------------------------------------------------------------------
// Arduino固有の関数 setup() :初期設定
//------------------------------------------------------------------
void setup()
{
//シリアル通信開始
//Serial.begin(115200);
//D9,D10 PWM キャリア周期:31kHz
// TCCR1 &= B11110000;
// TCCR1 |= B00000001;
//PWMを10bit化
//TCCR1A |= B00000011;
// TCCR0A = 2<<COM0A0 | 2<<COM0B0 | 3<<WGM00;
// TCCR0B = 0<<WGM02 | 1<<CS00;
// TCCR1 = 0<<PWM1A | 0<<COM1A0 | 1<<CS10;
// GTCCR = 1<<PWM1B | 2<<COM1B0;
#if 0
TCCR0A = 2<<COM0A0 | 2<<COM0B0 | 3<<WGM00; // B1111 0011
TCCR0B = 0<<WGM02 | 1<<CS00; // B0000 0001 分周無し
TCCR1 = 0<<PWM1A | 0<<COM1A0 | 1<<CS10;
GTCCR = 1<<PWM1B | 2<<COM1B0;
#endif
// TCCR1 =0x03;最初に0x03が設定されている。
// D9,D10 PWM キャリア周期:31kHz
// TCCR1 &= B11110000;
// TCCR1 |= B00000001;
//TCCR1 = 1<<CTC1 | 1<<PWM1A | 3<<COM1A0 | 1<<CS10;
TCCR1 = 0<<CTC1 | 0<<PWM1A | 0<<COM1A0 | 1<<CS10;
pinMode(O1, OUTPUT);
pinMode(O2, OUTPUT);
pinMode(O3, OUTPUT);
pinMode(O4, OUTPUT);
//DCCの応答用負荷ピン
#if defined(DCCACKPIN)
//Setup ACK Pin
pinMode(DccAckPin, OUTPUT);
digitalWrite(DccAckPin, 0);
#endif
#if !defined(DECODER_DONT_DEFAULT_CV_ON_POWERUP)
if ( Dcc.getCV(CV_MULTIFUNCTION_PRIMARY_ADDRESS) == 0xFF ) { //if eeprom has 0xFF then assume it needs to be programmed
//Serial.println("CV Defaulting due to blank eeprom");
notifyCVResetFactoryDefault();
} else {
//Serial.println("CV Not Defaulting");
}
#else
//Serial.println("CV Defaulting Always On Powerup");
notifyCVResetFactoryDefault();
#endif
// Setup which External Interrupt, the Pin it's associated with that we're using, disable pullup.
Dcc.pin(0, 2, 0); // Atiny85 7pin(PB2)をDCC_PULSE端子に設定
// Call the main DCC Init function to enable the DCC Receiver
Dcc.init( MAN_ID_DIY, 100, FLAGS_MY_ADDRESS_ONLY , 0 );
//Reset task
gPreviousL5 = millis();
//Init CVs
gCV1_SAddr = Dcc.getCV( CV_MULTIFUNCTION_PRIMARY_ADDRESS ) ;
//#if 0
gCV49_fx = Dcc.getCV( CV_49_F0_FORWARD_LIGHT );
switch(gCV49_fx){
case 0: ptn = ptn1;
break;
case 1: ptn = ptn1;
break;
case 2: ptn = ptn2;
break;
case 3: ptn = ptn3;
break;
case 4: ptn = ptn4;
break;
case 5: ptn = ptn5;
break;
case 6: ptn = ptn6;
break;
case 7: ptn = ptn7;
break;
case 8: ptn = ptn8;
break;
case 9: ptn = ptn9;
break;
case 10: ptn = ptn10;
break;
case 11: ptn = ptn11;
break;
}
gCV50_DimmingSpeed = Dcc.getCV( CV_DIMMING_SPEED ); // 減光スピード
gCV51_DimmingLightQuantity = Dcc.getCV( CV_DIMMING_LIGHT_QUANTITY ); // 減光レベル
gCV52_RoomDimming = Dcc.getCV( CV_ROOM_DIMMING );
//#endif
//デバック信号:起動
//注意:2016/4/9 このコメントを外し起動時にアドレスを点灯させるようにすると、
// loopにたどり着く時間が長くなり、CV書き込みが失敗します。
//LightMes(0);
//LightMes(Dcc.getCV(CV_MULTIFUNCTION_PRIMARY_ADDRESS));
//LightMes(gCV49_fx,8);
//O2 analog test 明るく点灯ぃて1秒後に暗くなる
//OCR1A有効 high出力 分周無し
#if 0
TCCR1 = 1<<PWM1A | 2<<COM1A0 | 1<<CS10;
OCR1A = 255;
delay(1000);
OCR1A = 12;
for(;;);
#endif
}
//---------------------------------------------------------------------
// Arduino main loop
//---------------------------------------------------------------------
void loop() {
// You MUST call the NmraDcc.process() method frequently from the Arduino loop() function for correct library operation
Dcc.process();
if ( (millis() - gPreviousL5) >= 10) // 100:100msec 10:10msec Function decoder は 10msecにしてみる。
{
//Headlight control
HeadLight_Control();
//Motor drive control
//Motor_Control();
//Reset task
gPreviousL5 = millis();
}
}
//---------------------------------------------------------------------
// HeadLight control Task (10Hz:100ms)
//---------------------------------------------------------------------
void HeadLight_Control()
{
uint16_t aPwmRef = 0;
if((gCV49_fx >= 2) && (gCV49_fx <= 11)) {
FXeffect_Control();
}
//---------------------------------------------------------------------
// ヘッド・テールライトコントロール
// CV49=20 設定で有効
// F0 で On/Off O2:head O3:tail
//---------------------------------------------------------------------
if(gCV49_fx == 20) {
if(gState_F0 > 0) {
if( gDirection == 0){ // Reverse 後進(DCS50Kで確認)
TCCR1 = 1<<CS10; // OCR1A 無効
OCR1A = 0; // O2:analog out (hedd light)
digitalWrite(O3, HIGH); // 点灯
} else { // Forward 前進(DCS50Kで確認)
digitalWrite(O3, LOW); // O3:tail light off
// OCR1A有効 high出力 分周無し
TCCR1 = 1<<PWM1A | 2<<COM1A0 | 1<<CS10;
if ( gSpeedRef > 1 ){//gCV50_DimmingSpeed ){ // 調光機能
aPwmRef = MAX_PWMDUTY; // 速度が1以上だったらMAX
} else {
aPwmRef = 10;//gCV51_DimmingLightQuantity; // 減光レベル
}
OCR1A = aPwmRef; // O2:analog out (hedd light)
}
}
if(gState_F0 == 0){ // DCC F0 コマンドの処理
TCCR1 = 1<<CS10;
OCR1A = 0; // O2:analog out (hedd light)
digitalWrite(O2, LOW); // 消灯
digitalWrite(O3, LOW); // 消灯
}
}
//---------------------------------------------------------------------
// ヘッド・テールライトコントロール
// CV49=21 設定で有効
// F0 で On/Off O2:head O3:tail
//---------------------------------------------------------------------
if(gCV49_fx == 21) {
if(gState_F0 > 0) {
if( gDirection == 1){ // Reverse 前進(DCS50Kで確認)
digitalWrite(O2, HIGH);
digitalWrite(O3, LOW);
} else { // Forward 後進(DCS50Kで確認)
digitalWrite(O2, LOW);
digitalWrite(O3, HIGH);
}
}
if(gState_F0 == 0) {
digitalWrite(O2, LOW);
digitalWrite(O3, LOW);
}
}
//---------------------------------------------------------------------
// ヘッド・テールライトコントロール
// CV49=0,1 設定で有効
// F0 で Head Light On/Off F1 Tail Light On/Off F3 HEAD sign F5 room
//---------------------------------------------------------------------
// F0 受信時の処理
//#if
if((gCV49_fx != 20)||(gCV49_fx != 20)) {
if(gState_F0 == 0){
digitalWrite(O2, LOW);
} else {
digitalWrite(O2, HIGH);
}
//#endif
// F1 受信時の処理
//#if
if(gState_F1 == 0){
digitalWrite(O3, LOW);
} else {
digitalWrite(O3, HIGH);
}
//#endif
}
//---------------------------------------------------------------------
// ヘッド・テールライトコントロール
// F3 と F5の処理
//---------------------------------------------------------------------
// F2 受信時の処理
// DCS50KのF2は1shotしか光らないので、コメントアウト
#if 0
if(gCV49_fx < 20 ) { // CV49 が20 または21 以外有効
if(gState_F2 == 0){
digitalWrite(O2, LOW);
} else {
digitalWrite(O2, HIGH);
}
}
#endif
// F3 受信時の処理
//#if 0
if(gState_F3 == 0){
digitalWrite(O1, LOW);
} else {
digitalWrite(O1, HIGH);
}
//#endif
// F4 受信時の処理
#if 0
if(gState_F4 == 0){
digitalWrite(O4, LOW);
} else {
digitalWrite(O4, HIGH);
}
#endif
// F5 受信時の処理
if(gState_F5 == 0){
GTCCR = 0 << PWM1B | 0 << COM1B0;
analogWrite(O4, 0);
digitalWrite(O4, LOW); // 消灯
} else {
GTCCR = 1 << PWM1B | 2 << COM1B0;
analogWrite(O4,gCV52_RoomDimming);
}
}
//DCC速度信号の受信によるイベント
//extern void notifyDccSpeed( uint16_t Addr, uint8_t Speed, uint8_t ForwardDir, uint8_t MaxSpeed )
extern void notifyDccSpeed( uint16_t Addr, DCC_ADDR_TYPE AddrType, uint8_t Speed, DCC_DIRECTION Dir, DCC_SPEED_STEPS SpeedSteps )
{
if (Speed > 64) {
// if(doing_Resets_Flag == false) {
doing_Resets_Flag = true;
notifyDccReset(0);
// }
}
else {
doing_Resets_Flag = false;
}
// if ( gDirection != ForwardDir) // old NMRA
if ( gDirection != Dir )
{
// gDirection = ForwardDir; // old NMRA
gDirection = Dir;
}
gSpeedRef = Speed;
}
//---------------------------------------------------------------------
// FX効果ステートマシン
// 10ms周期で起動
// unsigned chart ptn[4][5]{{'I',0,0,1},{'S',20,255,1},{'S',40,0,1},{'E',0,0,1}};
//---------------------------------------------------------------------
void FXeffect_Control(){
static char state = 0; // ステート
static unsigned char adr = 0; // アドレス
static int timeUp = 0; // 時間
static float delt_v = 0; // 100msあたりの増加量
static float pwmRef =0;
if(gState_F0 == 0){ // F0 OFF
state = 0;
adr = 0;
timeUp = 0;
pwmRef = 0;
// OCR1A無効 OCR1A未使用 分周無し O2:消灯させる
TCCR1 = 1<<CS10;
digitalWrite(O2, LOW); // PB1:O2:6pin LOW出力
}
S00:
switch(state){
case 0: // S00:idel
if(gState_F0 >0){ // F0 ON
adr = 0;
timeUp = 0;
pwmRef = 0;
// OCR1A有効 high出力 分周無し
TCCR1 = 1<<PWM1A | 2<<COM1A0 | 1<<CS10;
OCR1A = 0;
state = 1;
goto S00; // 100ms待たずに再度ステートマシーンに掛ける
}
break;
case 1: // S01:コマンド処理
if( ptn[adr][0]=='I'){ // I:初期化
timeUp = ptn[adr][1];
pwmRef = ptn[adr][2];
delt_v = 0; // 変化量0
OCR1A = (unsigned char)pwmRef; // O2:analog out (hedd light)
adr++;
state = 1;
goto S00; // 100ms待たずに再度ステートマシーンに掛ける
} else if( ptn[adr][0]=='E'){ // E:end
state = 3;
} else if( ptn[adr][0]=='L' ){ // L:Loop
adr = 0;
state =1;
goto S00; // 100ms待たずに再度ステートマシーンに掛ける
} else if( ptn[adr][0]=='O' ){ // O:出力
timeUp = ptn[adr][1];
pwmRef = ptn[adr][2];
delt_v = 0;
state = 2;
} else if( ptn[adr][0]=='S' ){ // S:sweep
timeUp = ptn[adr][1];
delt_v = (ptn[adr][2]-pwmRef)/timeUp; // 変化量を算出
state = 2;
}
break;
case 2: // S02:時間カウント
timeUp--;
pwmRef = pwmRef + delt_v;
if(pwmRef<=0){ // 下限、上限リミッタ
pwmRef = 0;
} else if(pwmRef>=255){
pwmRef = 255;
}
OCR1A = (unsigned char)pwmRef; // O2:analog out (hedd light)
if( timeUp <= 0 ){
adr ++;
state = 1; //次のコマンドへ
}
break;
case 3: // stay
break;
default:
break;
}
}
//---------------------------------------------------------------------------
//ファンクション信号受信のイベント
//FN_0_4とFN_5_8は常時イベント発生(DCS50KはF8まで)
//FN_9_12以降はFUNCTIONボタンが押されたときにイベント発生
//前値と比較して変化あったら処理するような作り。
//---------------------------------------------------------------------------
//extern void notifyDccFunc( uint16_t Addr, FN_GROUP FuncGrp, uint8_t FuncState)
extern void notifyDccFunc(uint16_t Addr, DCC_ADDR_TYPE AddrType, FN_GROUP FuncGrp, uint8_t FuncState)
{
if ( doing_Resets_Flag == true ) {
return;
}
if( FuncGrp == FN_0_4)
{
if( gState_F0 != (FuncState & FN_BIT_00))
{
//Get Function 0 (FL) state
gState_F0 = (FuncState & FN_BIT_00);
}
if( gState_F1 != (FuncState & FN_BIT_01))
{
//Get Function 1 state
gState_F1 = (FuncState & FN_BIT_01);
}
if( gState_F2 != (FuncState & FN_BIT_02))
{
gState_F2 = (FuncState & FN_BIT_02);
}
if( gState_F3 != (FuncState & FN_BIT_03))
{
gState_F3 = (FuncState & FN_BIT_03);
}
if( gState_F4 != (FuncState & FN_BIT_04))
{
gState_F4 = (FuncState & FN_BIT_04);
}
}
if( FuncGrp == FN_5_8)
{
if( gState_F5 != (FuncState & FN_BIT_05))
{
//Get Function 0 (FL) state
gState_F5 = (FuncState & FN_BIT_05);
}
if( gState_F6 != (FuncState & FN_BIT_06))
{
//Get Function 1 state
gState_F6 = (FuncState & FN_BIT_06);
}
if( gState_F7 != (FuncState & FN_BIT_07))
{
gState_F7 = (FuncState & FN_BIT_07);
}
if( gState_F8 != (FuncState & FN_BIT_08))
{
gState_F8 = (FuncState & FN_BIT_08);
}
}
}
//-----------------------------------------------------
// F4 を使って、メッセージを表示させる。
//上位ビットから吐き出す
// ex 5 -> 0101 -> ー・ー・
//-----------------------------------------------------
void LightMes( char sig ,char set)
{
char cnt;
for( cnt = 0 ; cnt<set ; cnt++ ){
if( sig & 0x80){
digitalWrite(O1, HIGH); // 短光
delay(200);
digitalWrite(O1, LOW);
delay(200);
} else {
digitalWrite(O1, HIGH); // 長光
delay(1000);
digitalWrite(O1, LOW);
delay(200);
}
sig = sig << 1;
}
delay(400);
}
//-----------------------------------------------------
// Debug用Lチカ
//-----------------------------------------------------
void pulse()
{
digitalWrite(O1, HIGH); // 短光
delay(100);
digitalWrite(O1, LOW);
}