Сделать имитацию сигнала

Stempler
Offline
Зарегистрирован: 09.06.2019

Доброго всем времени суток форумчане, подскажите пожалуйста, как можно съимитировать такой вот сигнал, посредствам Arduino UNO? Может быть есть какой-либо готовый скетч,который можно подправить.

Фото сигнала прикрепляю.

ps Ардуино начал заниматься очень недавно, не обессудьте за вопрос.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

1. Похоже на сигнал последовательного порта.

2. Максимальная ширина картинки на форуме 780 пикселей. Если вставляете картинки, следите за тем, чтобы они были не шире (установите нужную ширину окна программы, не нужно снимать картинку с поного экрана).

Stempler
Offline
Зарегистрирован: 09.06.2019

Принял, пардон за картинку, беру на заметку.

Как такой можно выдать ардуиной?

qbit
Offline
Зарегистрирован: 18.03.2019

Stempler пишет:

...Как такой можно выдать ардуиной?

Вы можете обойтись и без ардуинки. Как выше #1 andriano абсолютно правильно подметил что Ваш сигнал сольно похож на TTL RS232. Идет [Start]1100'0100[Stop][Start]0110'1110[Stop]. Т.к. порядок следования обратный, то получается 23h 76h. Т.е. берете терминал, и шлете последовательность 23 76 (в hex-формате). Настройки порта - 1стоп бит, 8бит передачи, без проверки на паритет, скорость - согласно Вашему сигналу (по картинке не понять).

Stempler
Offline
Зарегистрирован: 09.06.2019

хм. К сожалению без ардуинки не обойтись, я хочу попробовать съимитировать этот сигнал, чтобы потом его принимать ардуинкой из другого аппарата.

qbit
Offline
Зарегистрирован: 18.03.2019

Например, так:

void task_signal( void );

// Назначаем порт для вывода сигнала
#define PIN_OUT 1
#define OUT_ON() digitalWrite( PIN_OUT, HIGH )
#define OUT_OFF() digitalWrite( PIN_OUT, LOW )

//Длительность бита
#define PEROID 100  // в мкс

// Битовая последовательность
bool bit_sequence[] = {
      0, 1, 1, 0, 0, 0, 1,
      0, 0, 1, 0, 0, 1, 1,
      0, 1, 1, 1, 0, 1
};

// таймер
unsigned long cnt_period;
unsigned long prev_micros;

// Индексный счетчик
unsigned int bit_index;

// Запуск последовательности
bool bit_sequence_start;

void setup() {
  Serial.begin( 115200 );
  Serial.print( "Array size " );
  Serial.print( sizeof( bit_sequence ) );
  Serial.println( "bits" );
  bit_index = 0;
  bit_sequence_start = true;
}

void loop() {
  // put your main code here, to run repeatedly:
  task_signal();
}

//////////
void task_signal( void ) {

unsigned long tmp_micros;

  if( bit_index ) {
    if( bit_sequence_start ) {
      tmp_micros = micros();
      cnt_period += tmp_micros - prev_micros;
      prev_micros = tmp_micros;
      if( cnt_period >= PEROID ) {
        cnt_period -= PEROID;
        bit_sequence[ bit_index++ ] ? OUT_ON() : OUT_OFF();
      }
      if( bit_index > sizeof( bit_sequence ) ) bit_sequence_start = false;
      
    }
  } else {
// Посылаем первый бит
    prev_micros = micros();
    cnt_period = 0;
    bit_sequence[ bit_index ] ? OUT_ON() : OUT_OFF();
  }
  
}

PS Код не проверялся, накидан в блокноте...

qbit
Offline
Зарегистрирован: 18.03.2019

Например, так:

void task_signal( void );

// Назначаем порт для вывода сигнала
#define PIN_OUT 1
#define OUT_ON() digitalWrite( PIN_OUT, HIGH )
#define OUT_OFF() digitalWrite( PIN_OUT, LOW )

//Длительность бита
#define PEROID 100  // в мкс

// Битовая последовательность
bool bit_sequence[] = {
      0, 1, 1, 0, 0, 0, 1,
      0, 0, 1, 0, 0, 1, 1,
      0, 1, 1, 1, 0, 1
};

// таймер
unsigned long cnt_period;
unsigned long prev_micros;

// Индексный счетчик
unsigned int bit_index;

// Запуск последовательности
bool bit_sequence_start;

void setup() {
  Serial.begin( 115200 );
  Serial.print( "Array size " );
  Serial.print( sizeof( bit_sequence ) );
  Serial.println( "bits" );
  bit_index = 0;
  bit_sequence_start = true;
}

void loop() {
  // put your main code here, to run repeatedly:
  task_signal();
}

//////////
void task_signal( void ) {

unsigned long tmp_micros;

  if( bit_index ) {
    if( bit_sequence_start ) {
      tmp_micros = micros();
      cnt_period += tmp_micros - prev_micros;
      prev_micros = tmp_micros;
      if( cnt_period >= PEROID ) {
        cnt_period -= PEROID;
        bit_sequence[ bit_index++ ] ? OUT_ON() : OUT_OFF();
      }
      if( bit_index > sizeof( bit_sequence ) ) bit_sequence_start = false;
      
    }
  } else {
// Посылаем первый бит
    prev_micros = micros();
    cnt_period = 0;
    bit_sequence[ bit_index ] ? OUT_ON() : OUT_OFF();
  }
  
}

PS Код не проверялся, накидан в блокноте...

qbit
Offline
Зарегистрирован: 18.03.2019

Например, так:


void task_signal( void );

// Назначаем порт для вывода сигнала
#define PIN_OUT 1
#define OUT_ON() digitalWrite( PIN_OUT, HIGH )
#define OUT_OFF() digitalWrite( PIN_OUT, LOW )

//Длительность бита
#define PEROID 100  // в мкс

// Битовая последовательность
bool bit_sequence[] = {
      0, 1, 1, 0, 0, 0, 1,
      0, 0, 1, 0, 0, 1, 1,
      0, 1, 1, 1, 0, 1
};

// таймер
unsigned long cnt_period;
unsigned long prev_micros;

// Индексный счетчик
unsigned int bit_index;

// Запуск последовательности
bool bit_sequence_start;

void setup() {
  Serial.begin( 115200 );
  Serial.print( "Array size " );
  Serial.print( sizeof( bit_sequence ) );
  Serial.println( "bits" );
  bit_index = 0;
  bit_sequence_start = true;
}

void loop() {
  // put your main code here, to run repeatedly:
  task_signal();
}

//////////
void task_signal( void ) {

unsigned long tmp_micros;

  if( bit_index ) {
    if( bit_sequence_start ) {
      tmp_micros = micros();
      cnt_period += tmp_micros - prev_micros;
      prev_micros = tmp_micros;
      if( cnt_period >= PEROID ) {
        cnt_period -= PEROID;
        bit_sequence[ bit_index++ ] ? OUT_ON() : OUT_OFF();
      }
      if( bit_index > sizeof( bit_sequence ) ) bit_sequence_start = false;
      
    }
  } else {
// Посылаем первый бит
    prev_micros = micros();
    cnt_period = 0;
    bit_sequence[ bit_index++ ] ? OUT_ON() : OUT_OFF();
  }
  
}

PS Код не проверялся, накидан в блокноте...

qbit
Offline
Зарегистрирован: 18.03.2019

Извините по повтор...

b707
Offline
Зарегистрирован: 26.05.2017

qbit - вам уже вроде говорили, что вы с временными интервалами работаете неправильно. И даже показывали, как надо. Продолжаете жрать кактус?

 

UPDATE - прошу прощения, вы там столько накрутили, что сразу не разглядел. По внимательному прочтению грубых ошибок нет, просто все в три раза длинеее, чем надо. И куча лишних переменных. Зачем при каждом заъходе в процедуру прибавлять прошедшее время к cnt_period. а по окончании - вычитать из него?

Если не ошибаюсь, вот этот код полностью эквиватентем вашей процедуре

void task_signal( void ) {

 if( bit_sequence_start ) {
      
      if( (micros() - prev_micros) >= PEROID ) {
        prev_micros = micros();
        bit_sequence[ bit_index++ ] ? OUT_ON() : OUT_OFF();
      }
      if( bit_index > sizeof( bit_sequence ) ) bit_sequence_start = false;
      
    }
 }

 

sadman41
Offline
Зарегистрирован: 19.10.2016

Так если Sealeae его распознал, как сериал, то не проще ль .write() сделать?

qbit
Offline
Зарегистрирован: 18.03.2019

b707 пишет:

...И даже показывали, как надо. Продолжаете жрать кактус?...

О чем речь? Что, где и когда "показывали"? 

b707 пишет:

...И куча лишних переменных. Зачем при каждом заъходе в процедуру прибавлять прошедшее время к cnt_period. а по окончании - вычитать из него?...

"Лишние" переменные не случайны. Меджу 5 и 6 строками у Вас просткакивают лишние тики, которые никак не учитываются и которые дадут изменение в битовой скорости. Я думаю, Вы согласитесь, что зачение micros() в указанных строках разное. 

SLKH
Offline
Зарегистрирован: 17.08.2015

qbit пишет:

b707 пишет:

...И даже показывали, как надо. Продолжаете жрать кактус?...

О чем речь? Что, где и когда "показывали"? 

b707 пишет:

...И куча лишних переменных. Зачем при каждом заъходе в процедуру прибавлять прошедшее время к cnt_period. а по окончании - вычитать из него?...

"Лишние" переменные не случайны. Меджу 5 и 6 строками у Вас просткакивают лишние тики, которые никак не учитываются и которые дадут изменение в битовой скорости. Я думаю, Вы согласитесь, что зачение micros() в указанных строках разное. 

несложно лечится заменой одной строки:

05 if( (micros() - prev_micros) >= PEROID ) {

06 prev_micros -= PEROID; // вместо  prev_micros = micros(); и всей эквилибристики

// и т.д.

qbit
Offline
Зарегистрирован: 18.03.2019

SLKH пишет:

...

несложно лечится заменой одной строки:

06 prev_micros -= PEROID; // вместо  prev_micros = micros(); и всей эквилибристики

...

У Вас переменная prev_micros не такает, только вычитаете период. Для этого в #7 и и была введена промежуточная переменная tmp_micros.

qbit
Offline
Зарегистрирован: 18.03.2019

Stempler пишет:

...чтобы потом его принимать ардуинкой из другого аппарата.

Это существенно все меняет. Берите готовые библиотеки для работы с 1wire.

b707
Offline
Зарегистрирован: 26.05.2017

qbit пишет:

"Лишние" переменные не случайны. Меджу 5 и 6 строками у Вас просткакивают лишние тики, которые никак не учитываются и которые дадут изменение в битовой скорости. Я думаю, Вы согласитесь, что зачение micros() в указанных строках разное. 

ну хорошо, давайте добавим одну строчку к моему коду, чтобы решить эту "проблему". Будет девять непустых строк вместо ваших 19-ти. 

void task_signal( void ) {

 if( bit_sequence_start ) {
      tmp_micros = micros();
      if( ( tmp_micros - prev_micros) >= PEROID ) {
        prev_micros = tmp_micros;
        bit_sequence[ bit_index++ ] ? OUT_ON() : OUT_OFF();
      }
      if( bit_index > sizeof( bit_sequence ) ) bit_sequence_start = false;
      
    }
 }

А вот все эти пляски с вычитанием и прибавлением интервалов НА КАЖДОМ ПРОХОДЕ loop  - зачем они в вашем коде?

Stempler
Offline
Зарегистрирован: 09.06.2019

qbit пишет:

Например, так:


void task_signal( void );

// Назначаем порт для вывода сигнала
#define PIN_OUT 1
#define OUT_ON() digitalWrite( PIN_OUT, HIGH )
#define OUT_OFF() digitalWrite( PIN_OUT, LOW )

//Длительность бита
#define PEROID 100  // в мкс

// Битовая последовательность
bool bit_sequence[] = {
      0, 1, 1, 0, 0, 0, 1,
      0, 0, 1, 0, 0, 1, 1,
      0, 1, 1, 1, 0, 1
};

// таймер
unsigned long cnt_period;
unsigned long prev_micros;

// Индексный счетчик
unsigned int bit_index;

// Запуск последовательности
bool bit_sequence_start;

void setup() {
  Serial.begin( 115200 );
  Serial.print( "Array size " );
  Serial.print( sizeof( bit_sequence ) );
  Serial.println( "bits" );
  bit_index = 0;
  bit_sequence_start = true;
}

void loop() {
  // put your main code here, to run repeatedly:
  task_signal();
}

//////////
void task_signal( void ) {

unsigned long tmp_micros;

  if( bit_index ) {
    if( bit_sequence_start ) {
      tmp_micros = micros();
      cnt_period += tmp_micros - prev_micros;
      prev_micros = tmp_micros;
      if( cnt_period >= PEROID ) {
        cnt_period -= PEROID;
        bit_sequence[ bit_index++ ] ? OUT_ON() : OUT_OFF();
      }
      if( bit_index > sizeof( bit_sequence ) ) bit_sequence_start = false;
      
    }
  } else {
// Посылаем первый бит
    prev_micros = micros();
    cnt_period = 0;
    bit_sequence[ bit_index++ ] ? OUT_ON() : OUT_OFF();
  }
  
}

PS Код не проверялся, накидан в блокноте...

 

Огромное спасибо, сижу разбираюсь).

 Вижу вы опытный человек, могли бы подсказать пожалуйста еще по одному вопросу?

Как сделать так, чтобы если на пин ардуино приходит этот сигнал (0x23,0x76) делает одно действие, если другой сигнал - другое? Заранее ОГРОМНОЕ спасибо!

qbit
Offline
Зарегистрирован: 18.03.2019

Stempler пишет:

...Как сделать так, чтобы если на пин ардуино приходит этот сигнал (0x23,0x76) делает одно действие, если другой сигнал - другое? Заранее ОГРОМНОЕ спасибо!

Я понимаю, крткость - сестра таланта...

Т.е. все на одной ардуинке - одна функция передает, другая функция принимает?

Каркас функции с действиями и задачи (накидан в блокноте...):

// Структура действий с кодами
typedef enum {

    TASK_ACTION_NULL = 0,
    TASK_ACTION_1 = 0x23,
    TASK_ACTION_2 = 0x76

} TASK_ACTIONS;

// Коды шибок задач
typedef enum {

    TASK_ACTION_NULL = 0
    TASK_ACTION_OK,
    TASK_ACTION_ERROR,
    TASK_ACTION_ERROR1,
    TASK_ACTION_ERROR2,
    TASK_ACTION_NOT_KNOWN

} TASK_ACTIONS_ERRORS;


// Прототипы функций
TASK_ACTIONS_ERRORS task_action( TASK_ACTIONS * );
TASK_ACTIONS_ERRORS  task_1( void * );
TASK_ACTIONS_ERRORS  task_2( void * );




//////////////////////////////////////////
//
// Функция действий
//
TASK_ACTIONS_ERRORS task_action( TASK_ACTIONS *pta ){

TASK_ACTIONS_ERRORS ta_err = TASK_ACTION_ERROR;

	switch( *pta ) {

// Нет задач			
		case TASK_ACTION_NULL:
			ta_err = TASK_ACTION_NULL;
			break;

// Задача 1
		case TASK_ACTION_1:
			ta_err = ( task_1() != TASK_ACTION_OK ) ? TASK_ACTION_ERROR1 : TASK_ACTION_OK;
			break

// Задача 2
		case TASK_ACTION_2:
			ta_err = ( task_2() != TASK_ACTION_OK )  ? TASK_ACTION_ERROR2 : TASK_ACTION_OK;
			break;

// Неизвестная задача
		
			ta_err = TASK_ACTION_NOT_KNOWN;
			break;

	}
	return ta_err;
}


//////////////////////////////////////////
//
// Задача 1
//
TASK_ACTIONS_ERRORS  task_1( void * p ) {

 TASK_ACTIONS_ERRORS ta_err = TASK_ACTION_ERROR;

// Ваш код
...
...
// Успешное выполнение Вашего кода
	ta_err = TASK_ACTION_OK;
//
	return ta_err;
}

//////////////////////////////////////////
//
// Задача 2
//
TASK_ACTIONS_ERRORS  task_2( void * p ) {

 TASK_ACTIONS_ERRORS ta_err = TASK_ACTION_ERROR;

// Ваш код
...
...
// Успешное выполнение Вашего кода
	ta_err = TASK_ACTION_OK;
//
	return ta_err;
}

 

А можно проще

int actions;

...

switch( actions ) {

case 0x23:

// Задача 1

break;

case 0x76:

// Задача 2

break;

}

 

sadman41
Offline
Зарегистрирован: 19.10.2016

Опять управление холодильника что ли? ;)

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

sadman41 пишет:

Опять управление холодильника что ли? ;)

так жара на дворе, сейчас холодильщики и кондиционерщики на расхват )))

b707
Offline
Зарегистрирован: 26.05.2017

точно жара.

qbit -  "настоящему мужику всегда есть что сказать" ?

maxxx070
Offline
Зарегистрирован: 23.05.2019

А куда при этом подключаться? Я просто не увидел инициализацию пинов)

maxxx070
Offline
Зарегистрирован: 23.05.2019

b707 пишет:

точно жара.

qbit -  "настоящему мужику всегда есть что сказать" ?

тоже пробую. вот так?)

 

int actions;

void setup() // процедура setup
{
pinMode(7, OUTPUT); // о
}

void loop() 
{
  switch( actions ) {

case 0x23:

digitalWrite(7, HIGH); 

break;



  }
}

 

b707
Offline
Зарегистрирован: 26.05.2017

maxxx070 - код, написанный qbit - это очень грубая заготовка, от готового проекта его отделяет примерно столько же, как муку и дрожжи от готового пирожка :)