プロが教えるわが家の防犯対策術!

C言語初心者です.
LEDを以下のように点灯させるプログラムをC言語でつくりたいのですが,わからなくて困っており,質問させていただきました.
「LEDを1秒間点灯させ,0.5秒間消灯させ,また1秒間点灯させ,次は0.6秒間消灯させるというように消灯時間を0.1秒おきに増やしていき,消灯時間を1.5秒間まで増やした後,今度は0.1秒おきに消灯時間を減らしていき,消灯時間を0.5秒間まで減らし,これを繰り返す.」(分かりづらくてすみません…)
というようなプログラムはどのようにつくればいいでしょうか?

ちなみに1秒おきに点灯,消灯を繰り返すプログラムは,メイン関数を
void main()
{
while(1){
LED1_ON();
delay_us(1000);
LED1_OFF();
delay_us(1000);
}
}
とすることで出来ました.

A 回答 (2件)

まず、



while(1)
{
LED1_ON();delay_ms(1000);
LED1_OFF();delay_ms(1000);
}

で、本当に、1秒間隔になっていることを確認してください。
次は、

int timeON = 1000;
int timeOFF = 1000;

while(1)
{
LED1_ON();delay_ms(timeON);
LED1_OFF();delay_ms(timeOFF);
}

を確認してください。
このあと、timfOFF を 500 とか、800 とかに変更して確認してみてください。
ここでおかしいようだと、delay_ms() の設計ミスで、異なる引数で呼ばれたときにおかしな事が起きているというのが考えられます。

ここまで大丈夫だと、タイミングがおかしいのは気のせいのような気がしますが。

あとは、


LED1_ON();delay_ms(500);
LED1_OFF();delay_ms(1000);

LED1_ON();delay_ms(600);
LED1_OFF();delay_ms(1000);

LED1_ON();delay_ms(700);
LED1_OFF();delay_ms(1000);

LED1_ON();delay_ms(800);
LED1_OFF();delay_ms(1000);

という感じで、点滅の感覚をつかむと良いかもしれません。
    • good
    • 0
この回答へのお礼

while(1)
{
LED1_ON();delay_ms(1000);
LED1_OFF();delay_ms(1000);
}
これはちゃんと1秒間隔で大丈夫でしたが

int timeON = 1000;
int timeOFF = 1000;

while(1)
{
LED1_ON();delay_ms(timeON);
LED1_OFF();delay_ms(timeOFF);
}
これで明らかにはやくなりました.
そしてtimeOFFの数値を変更しても点滅の間隔は変わりませんでした.
ありがとうございました

お礼日時:2010/11/15 17:26

ほとんどできている気がしますけど。


あとは、ループで繰り返すだけで。

ちょっと書き換えると、1秒ON/1秒OFF のプログラムは、
void main()
{
while(1){
LED1_ON(); delay_us(1000);
LED1_OFF(); delay_us(1000);
}
}

です。(改行を変更しただけです。これで、1秒(1000ms)ON している様子がわかると思います)
これを、timeON ms と timeOFF ms の点滅に書き換えると、

void main()
{
int timeON = 1000;
int timeOFF = 1000;

while(1){
LED1_ON(); delay_us(timeON);
LED1_OFF(); delay_us(timeOFF);
}
}

消灯時間を毎回増やすには、

whie(1)
{
for (timeOFF = 500; timeOFF <= 1500; timeOFF += 100)
{
点滅の処理
}
}

というループにするだけです。
この後減らすところも安直に作るなら、

whie(1)
{
for (timeOFF = 500; timeOFF <= 1500; timeOFF += 100)
{
点滅の処理
}

for (timeOFF = 1400; timeOFF >= 600; timeOFF -= 100)
{
点滅の処理
}

}

で、その動きにはなると思います(確認してませんけど)
これは、「点滅の処理」という同じものが2カ所出てくるので、関数なんかにして独立させると良いかと思います。


そのほかにもバリエーションがあって、

int timeOFFList[] =
{500, 600, 700, 800, 900, 1000, 1100, 1200, 1300, 1400, 1500,
1400, 1300, 1200, 1100, 1000, 900, 800, 700, 600, -1};

で、

int i = 0;
while(1)
{
timeOFF = timeOFFList[i];
点滅の処理
i++;
if (timeOFFList[i] < 0) i = 0;
}

とか。
これは、データを作る(というか書く)のが面倒ですが、制御の流れ自体は追いかけやすいと思います。

あと、増減をひとつのループでやってみる場合、考え方として、「増減」の制御はややこしいです。
ただ、増減というのは、途中で折り返すと[増加」なのですね。

while(1)
{
for(timeOFFWork = 500; timeOFFWork < 2400; timeOFFWork += 100)
{
timeOFF = (timeOFFWork > 1500) ? 3000 - timeOFFWork : timeOFFWork;
点滅の処理
}
}

という制御もありかなと思います。
こちらは、あとから、「なに? この意味不明な計算」となりかねない気はします。

この回答への補足

順を追ったわかりやすい説明有難うございます!
void main(void)
{

int timeON = 1000;
int timeOFF;

while(1)
{
for (timeOFF = 500; timeOFF <= 1500; timeOFF += 100)
{
LED1_ON();delay_ms(timeON);
LED1_OFF();delay_ms(timeOFF);
}

for (timeOFF = 1400; timeOFF >= 600; timeOFF -= 100)
{
LED1_ON();delay_ms(timeON);
LED1_OFF();delay_ms(timeOFF);
}
}

}
というプログラムでやったところ点滅は一定間隔ではなさそうなのですが,あきらかに1秒よりも早い早さで点滅をしてしまいました.どこかミスがあるのでしょうか; ちなみに間違って書いてしまったのですがusではなくmsでした.

補足日時:2010/11/15 15:43
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!