Непонятки с передним фронтом

vov4ik
Offline
Зарегистрирован: 10.09.2013

В конце программы создал несеметричный мультивибратор который на 100миллисек выдаёт 1 в 15сек, далее выделение переднего фронта, тоесть измерение и выдача в порт происходит один раз в 15сек по условию if(trgrt1).

String TS;
bool trgrt1 = 0;
bool trgrt2 = 0;
bool trgrt3 = 0;
void setup()
{
   Serial.begin(9600);
  analogReference(INTERNAL);
pinMode(3, INPUT);// Замкнуть на 5В
pinMode(10, OUTPUT); //хз
}
void loop()
{
if(trgrt1)
 {
TS= (String(float (analogRead (0)/ 9.31))); // LM35
Serial.print("sensor = " );
Serial.println(digitalRead (3));
 Serial.print("temp  " );
 Serial.println(TS);
 }
trgrt3 = (!((millis()%15000) - (millis()%15000)%100)); // блинк 15 сек на 100 мсек
trgrt1 = 0;
if (!trgrt3) {trgrt2 = 1;}
if (trgrt3 && trgrt2) {trgrt1 = 1; trgrt2 = 0;}
delay (1);
 }

Всё работает но если убрать delay (1); , в порт прилетает 1-4 сигнала.

Почему так ???

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

или я не понял, или код странный

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

22 строка. Это зачем считать разницу между соседними вызовами millis? Да еще со страшным %15000. Я бы еще понял, считать разницу между текущим значением millis и сохраненным. Тогда можно измерять временные интервалы, а если не сохранять, то выдержать интервал не получится.

Не работает, потому что логика странная, если объясните, разве что, но лично я не догоняю.

Может проще задачу сформулировать? Вам нужно раз в 15 секунд прочитать данные с пина A0 и выдать в Serial, так?

Сейчас вообще непонятно, зачем Вам мультивибратор, да еще несимметричный, да еще и на 100мс выдающий единицу (куда то выдающий).

 

vov4ik
Offline
Зарегистрирован: 10.09.2013

А что не понятного условие if(trgrt1) должно выполнятся один раз в 15 сек.

(!((millis()%15000) - (millis()%15000)%100)) формирует сигнал если с периудом в 1 сек 0 0 0 0 0 0 0 0 0 0 0 0 0 1 

void setup() {
  Serial.begin(9600);
}
void loop() {
Serial.print(!((millis()%1500) - (millis()%1500)%100)); 
}
 выход с порта 11111111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111111111111111111111111
1111111110000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000

24  if (!trgrt3) {trgrt2 = 1;} тут я думаю понятно когда нули trgrt2 = 1

25 if (trgrt3 && trgrt2) {trgrt1 = 1; trgrt2 = 0;} когда 1 и trgrt2 = 1 тогда trgrt1 = 1; trgrt2 = 0;

далее выполнение условия if(trgrt1)

23 trgrt1 = 0;

когда нули выполняется 24 как только появляется первая 1 выполняется один раз 25, с делей всё работает, но почему если убрать проскакивает несколько.

 

vov4ik
Offline
Зарегистрирован: 10.09.2013

Программа сильно растянется булет куча условий, экран, SD карта и часы, на сиди карту один раз в 15 сек должна будет производится запись, привязка к часам не получится, SPI тяпает много времени (к примеру вывод картинки на TFT примерно 3сек) и мне проще будет раздвинуть методом тыка несеметричный мультивибратор, к примеру 15 сек из которых 4 сек "1" ост "0".

Так та в принцепе всё работает но с делей, и у меня возникает просто вопрос почему тригер не отрабатывает.

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

Формировать не один сигнал ("выполнить измерение"), а сигнал длительностью 100мс, чтобы из него выдернуть фронт - это, с моей т.з. нонсенс и усложнение простой задачи. Но дело Ваше, настаивать не буду и помочь в этом сложном деле не смогу.

PS Я раньше использовал разные трюки, но потом, поработав в группе, пишу всегда тупо и просто. И в этом есть смысл, поверьте. Тупо - значит проще разобраться. Просто - значит поймет даже двоешник. Всё это вместе помогает писать программы с меньшим количеством ошибок и быстрее решать задачи.

PS2 И да, я millis в одном цикле никогда не вызываю два раза, проще сохранить в переменной и использовать её по назначению хоть десять раз. А так смысл такого трюка понятен, т.е. формирование "импульса" определенной длительности.

 

vov4ik
Offline
Зарегистрирован: 10.09.2013

kisoft пишет:

PS2 И да, я millis в одном цикле никогда не вызываю два раза, проще сохранить в переменной и использовать её по назначению хоть десять раз. А так смысл такого трюка понятен, т.е. формирование "импульса" определенной длительности.

Похоже что вы правы ввёл переменную unsigned long привязал её к миллес баг пропал, всё отрабатывает на ура.

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

Осталось посмотреть, что такое millis:

unsigned long millis()
{
	unsigned long m;
	uint8_t oldSREG = SREG;

	// disable interrupts while we read timer0_millis or we might get an
	// inconsistent value (e.g. in the middle of a write to timer0_millis)
	cli();
	m = timer0_millis;
	SREG = oldSREG;

	return m;
}

это уже так, скорей до кучи. Т.е. между двумя вызовами может тикнуть таймер.

Ну и прекрасно, раз работает :)