вместе не работают библиотеки adafruit_neopixel и VirtualWire (RadioHead )

nicelight
Offline
Зарегистрирован: 20.09.2016

Здравствуйте. Столкнулся с проблемой взаимодействия библиотеки для ленты WS2812 и rf передатчика на 433 Mhz. Выяснил, что библиотеки используют одинаковое прерывание по Timer1. Как подправить одну из этих библиотек на работу с Timer2, найти не смог. Товарищи с буржуйских форумов советуют продвинутую библиотеку RadioHead, работающую практически с любыми RF передатчиками (за исключением esp ). В этой библиотеке есть возможность, раскоментировав один define из файла *.cpp переключить ее на работу с таймером 2. Внимательно прочел, сделал все как по феншую, но та же беда в работе скетча.

Как только раскоменчиваю строчку pixels.show(); для отображения WS2812 ленты, приемная часть затыкается и ни одного пакета по радиоканалу на ардуинку более не проходит.

Прошу помощи для наладки взаимодействия цветной LED ленты и rf передатчика. 

Any suggastions?

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

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

Я переделывал её на второй таймер, но мне нужен был только приёмник (передатчик не был нужен). И ещё, я намертво забил туда скорость передачи 2000 (убрал параметр).

Если такое решение (только для приёмника и с фиксированной скоростью) устроит, могу дать.

nicelight
Offline
Зарегистрирован: 20.09.2016

Мне как раз нужен приемник и 2000 бод приемлемая скорость! В принципе мог бы и сам посидеть вспомнить регистры, но буду благодарен за Вашу библиотеку :)

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Ну, давайте, потихоньку. Чтобы Вы могли запустить мои примеры. Вам нужны мои файлы.

Значит у меня есть два файла, которые надо расположить как библиотеки:

1. FS1000A.h - это просто небольшая обёртка вокруг VirtualWire. Мне удобнее работать с нею, чем в оригинальной VirtualWire. Посмотрите на её функции - поймёте почему. Она нуждается в оригинальной VirtualWire и всё делает через неё. Там ничего не поменено.  Эту "библиотеку" использует передатчик из моего примера.

2. FS1000A_V.h - этот файл уже включает в себя переделанную VirtualWire, т.е. оригинальная VirtualWire ему не нужна. Реализован только приёмник. Всё работает на втором таймере. Эту "библиотеку" использует приёмник из моего примера.

Ещё раз, эти файлы ставим как библиотеки (в сответсвующие папки).

Вот все файлы.

FS1000A.h

#ifndef  FS1000A_h
#define  FS1000A_h

#include <VirtualWire.h>

//////////////////////////////////////////////////////////////////////////////////////
//
// ФУНКЦИИ ПЕРЕДАТЧИКА
//

///////////////////////////////////////////////////
//
//	Инициализация передатчика
//
inline static void FS1000A_Init(const int8_t pin) {
	pinMode(pin, OUTPUT);
	vw_set_ptt_inverted(true);
	vw_setup(2000);
	vw_set_tx_pin(pin);
}

///////////////////////////////////////////////////
//
//	Ждать завершения передачи сообщения
//
inline static void FS1000A_WaitForTransmission(void) {
   vw_wait_tx();
}

///////////////////////////////////////////////////
//
//	Отправить сообщение из буфера buf длиной len
// если waitForTransmission - true, то дождаться завершения отправки
// иначе вернуться сразу же.
//
inline static void FS1000A_Send(const byte * buf, const byte len, const bool waitForTransmission = true) {
   vw_send((byte *)buf, (byte)len);
	if (waitForTransmission) FS1000A_WaitForTransmission();
}

///////////////////////////////////////////////////
//
//	Отправить строку s без завершающего 0
// если waitForTransmission - true, то дождаться завершения отправки
// иначе вернуться сразу же.
//
inline static void FS1000A_Send(const char * s, const bool waitForTransmission = true) {
   FS1000A_Send((const byte *) s, strlen(s), waitForTransmission);
}

///////////////////////////////////////////////////
//
//	Возвращает true если идёт передача
//
inline bool FS1000A_InProgress(void) {
   return vx_tx_active();
}

//////////////////////////////////////////////////////////////////////////////////////
//
// ФУНКЦИИ ПРИЁМНИКА
//

///////////////////////////////////////////////////
//
//	Инициализация приёмника
//
inline static void XY_MK_5V_Init(const int8_t pin)  {
	vw_set_ptt_inverted(true); 
	vw_setup(2000);	 
	vw_set_rx_pin(pin);
}

///////////////////////////////////////////////////
//
//	Включаем "слушание" эфира
//
inline static void XY_MK_5V_Start(void) {
	vw_rx_start(); 
}

///////////////////////////////////////////////////
//
//	Выключаем "слушание" эфира
//
inline static void XY_MK_5V_Stop(void) {
	vw_rx_stop(); 
}

///////////////////////////////////////////////////
//
//	Возвращает true если пришло сообщение
//
inline static bool XY_MK_5V_Available(void) {
   return vw_have_message();
}

///////////////////////////////////////////////////
//
//	Ждёт прихода сообщения указанное количество миллисекунд (если 0, то ждёт бесконечно)
// Возвращает true если дождалась и false в противном случае.
//
inline static bool XY_MK_5V_WaitForMessage(unsigned long milliseconds = 0) {
   if (milliseconds) return vw_wait_rx_max(milliseconds);
   vw_wait_rx();
   return true; 
}

///////////////////////////////////////////////////
//
//	Получает сообщение в буфер buf.
// Максимальная длина буфера должна находится в *len
// по завершении в *len будет реальная длина полученного сообщения
// возвращает true если сообщение получено нормально
//
inline static bool XY_MK_5V_ReceiveMessage(byte * buf, byte * len) {
   return vw_get_message(buf, len);
}
inline static bool XY_MK_5V_ReceiveMessage(char * s, byte * len) { 
   return XY_MK_5V_ReceiveMessage((byte *) s, len);
}

#endif   // FS1000A

FS1000A_V.h

#ifndef  FS1000A_V_h
#define  FS1000A_V_h

#include <arduino.h>
#include <stdint.h>

static inline uint16_t _crc_ccitt_update (uint16_t crc, uint8_t data) {
	data ^= crc & 0xff;
   data ^= data << 4;
   return ((((uint16_t)data << 8) | (crc >> 8)) ^ (uint8_t)(data >> 4) ^ ((uint16_t)data << 3));
}


#undef abs
#undef double
#undef round

#define VW_MAX_MESSAGE_LEN 30
#define VW_MAX_PAYLOAD VW_MAX_MESSAGE_LEN-3
#define VW_RX_RAMP_LEN 160
#define VW_RX_SAMPLES_PER_BIT 8
#define VW_RAMP_INC (VW_RX_RAMP_LEN/VW_RX_SAMPLES_PER_BIT)
#define VW_RAMP_TRANSITION VW_RX_RAMP_LEN/2
#define VW_RAMP_ADJUST 9
#define VW_RAMP_INC_RETARD (VW_RAMP_INC-VW_RAMP_ADJUST)
#define VW_RAMP_INC_ADVANCE (VW_RAMP_INC+VW_RAMP_ADJUST)
#define VW_HEADER_LEN 8

// The digital IO pin number of the receiver data
static uint8_t vw_rx_pin = 11;
// Current receiver sample
static uint8_t vw_rx_sample = 0;
// Last receiver sample
static uint8_t vw_rx_last_sample = 0;
static uint8_t vw_rx_pll_ramp = 0;
static uint8_t vw_rx_integrator = 0;
static uint8_t vw_rx_active = 0;

// Flag to indicate that a new message is available
static volatile uint8_t vw_rx_done = 0;

// Flag to indicate the receiver PLL is to run
static uint8_t vw_rx_enabled = 0;

// Last 12 bits received, so we can look for the start symbol
static uint16_t vw_rx_bits = 0;

// How many bits of message we have received. Ranges from 0 to 12
static uint8_t vw_rx_bit_count = 0;

// The incoming message buffer
static uint8_t vw_rx_buf[VW_MAX_MESSAGE_LEN];

// The incoming message expected length
static uint8_t vw_rx_count = 0;

// The incoming message buffer length received so far
static volatile uint8_t vw_rx_len = 0;

// Number of bad messages received and dropped due to bad lengths
static uint8_t vw_rx_bad = 0;

// Number of good messages received
static uint8_t vw_rx_good = 0;

// 4 bit to 6 bit symbol converter table
// Used to convert the high and low nybbles of the transmitted data
// into 6 bit symbols for transmission. Each 6-bit symbol has 3 1s and 3 0s 
// with at most 3 consecutive identical bits
static uint8_t symbols[] = {
	0xd, 0xe, 0x13, 0x15, 0x16, 0x19, 0x1a, 0x1c,
	0x23, 0x25, 0x26, 0x29, 0x2a, 0x2c, 0x32, 0x34
};


// Compute CRC over count bytes.
// This should only be ever called at user level, not interrupt level
static uint16_t vw_crc(uint8_t *ptr, uint8_t count) {
	uint16_t crc = 0xffff;
	while (count-- > 0) crc = _crc_ccitt_update(crc, *ptr++);
	return crc;
}

// Convert a 6 bit encoded symbol into its 4 bit decoded equivalent
static uint8_t vw_symbol_6to4(uint8_t symbol)
{
	uint8_t i;
	// Linear search :-( Could have a 64 byte reverse lookup table?
	for (i = 0; i < 16; i++) if (symbol == symbols[i]) return i;
	return 0; // Not found
}

// Set the pin number for input receiver data
inline void vw_set_rx_pin(uint8_t pin) {
	vw_rx_pin = pin;
}

// Set the output pin number for transmitter PTT enable
//inline void vw_set_ptt_pin(uint8_t pin) {
//	vw_ptt_pin = pin;
//}

// Set the ptt pin inverted (low to transmit)
//void vw_set_ptt_inverted(uint8_t inverted) {
//	vw_ptt_inverted = inverted;
//}

// Called 8 times per bit period
// Phase locked loop tries to synchronise with the transmitter so that bit 
// transitions occur at about the time vw_rx_pll_ramp is 0;
// Then the average is computed over each bit period to deduce the bit value
void vw_pll() {
	// Integrate each sample
	if (vw_rx_sample) vw_rx_integrator++;

	if (vw_rx_sample != vw_rx_last_sample) {
		// Transition, advance if ramp > 80, retard if < 80
		vw_rx_pll_ramp += ((vw_rx_pll_ramp < VW_RAMP_TRANSITION)
			? VW_RAMP_INC_RETARD
			: VW_RAMP_INC_ADVANCE);
		vw_rx_last_sample = vw_rx_sample;
	} else {
		// No transition
		// Advance ramp by standard 20 (== 160/8 samples)
		vw_rx_pll_ramp += VW_RAMP_INC;
	}
	if (vw_rx_pll_ramp >= VW_RX_RAMP_LEN) {
		// Add this to the 12th bit of vw_rx_bits, LSB first
		// The last 12 bits are kept
		vw_rx_bits >>= 1;

		// Check the integrator to see how many samples in this cycle were high.
		// If < 5 out of 8, then its declared a 0 bit, else a 1;
		if (vw_rx_integrator >= 5)
			vw_rx_bits |= 0x800;

		vw_rx_pll_ramp -= VW_RX_RAMP_LEN;
		vw_rx_integrator = 0; // Clear the integral for the next cycle

		if (vw_rx_active) {
			// We have the start symbol and now we are collecting message bits,
			// 6 per symbol, each which has to be decoded to 4 bits
			if (++vw_rx_bit_count >= 12) {
				// Have 12 bits of encoded message == 1 byte encoded
				// Decode as 2 lots of 6 bits into 2 lots of 4 bits
				// The 6 lsbits are the high nybble
				uint8_t this_byte =
					(vw_symbol_6to4(vw_rx_bits & 0x3f)) << 4
					| vw_symbol_6to4(vw_rx_bits >> 6);

				// The first decoded byte is the byte count of the following message
				// the count includes the byte count and the 2 trailing FCS bytes
				// REVISIT: may also include the ACK flag at 0x40
				if (vw_rx_len == 0) {
					// The first byte is the byte count
					// Check it for sensibility. It cant be less than 4, since it
					// includes the bytes count itself and the 2 byte FCS
					vw_rx_count = this_byte;
					if (vw_rx_count < 4 || vw_rx_count > VW_MAX_MESSAGE_LEN) {
						// Stupid message length, drop the whole thing
						vw_rx_active = false;
						vw_rx_bad++;
						return;
					}
				}
				vw_rx_buf[vw_rx_len++] = this_byte;

				if (vw_rx_len >= vw_rx_count) {
					// Got all the bytes now
					vw_rx_active = false;
					vw_rx_good++;
					vw_rx_done = true; // Better come get it before the next one starts
				}
				vw_rx_bit_count = 0;
			}
		}
		// Not in a message, see if we have a start symbol
		else if (vw_rx_bits == 0xb38) {
			// Have start symbol, start collecting message
			vw_rx_active = true;
			vw_rx_bit_count = 0;
			vw_rx_len = 0;
			vw_rx_done = false; // Too bad if you missed the last message
		}
	}
}

void vw_setup() {
	uint16_t nticks = 125; // number of prescaled ticks needed
	uint8_t prescaler = 2;
	TCCR2A = _BV(WGM21); // Output Compare pins disconnected, CTC mode
	TCCR2B = prescaler;
	OCR2A = nticks;
	TIMSK2 |= _BV(OCIE2A);
	pinMode(vw_rx_pin, INPUT);
}

// Get the last message received (without byte count or FCS)
// Copy at most *len bytes, set *len to the actual number copied
// Return true if there is a message and the FCS is OK
uint8_t vw_get_message(uint8_t* buf, uint8_t* len) {
	uint8_t rxlen;
	// Message available?
	if (!vw_rx_done) return false;
	// Wait until vw_rx_done is set before reading vw_rx_len
	// then remove bytecount and FCS
	rxlen = vw_rx_len - 3;
	// Copy message (good or bad)
	if (*len > rxlen) *len = rxlen;
	memcpy(buf, vw_rx_buf + 1, *len);
	vw_rx_done = false; // OK, got that message thanks
		// Check the FCS, return goodness
	return (vw_crc(vw_rx_buf, vw_rx_len) == 0xf0b8); // FCS OK?
}

ISR(TIMER2_COMPA_vect) {
	if (vw_rx_enabled) {
		vw_rx_sample = digitalRead(vw_rx_pin);
		vw_pll();
	}
}


//////////////////////////////////////////////////////////////////////////////////////
//
// ФУНКЦИИ ПРИЁМНИКА
//

///////////////////////////////////////////////////
//
//	Инициализация приёмника
//
inline static void receiverInit(const int8_t pin)  {
//	vw_set_ptt_inverted(true); 
	vw_setup();	 
	vw_set_rx_pin(pin);
}

///////////////////////////////////////////////////
//
//	Включаем "слушание" эфира
//
inline static void receiverStart(void) {
	if (!vw_rx_enabled) {
		vw_rx_enabled = true;
		vw_rx_active = false; // Never restart a partial message
	}
}

///////////////////////////////////////////////////
//
//	Выключаем "слушание" эфира
//
inline static void receiverStop(void) {
	vw_rx_enabled = false;
}

///////////////////////////////////////////////////
//
//	Возвращает true если пришло сообщение
//
inline static bool receiverAvailable(void) {
	return vw_rx_done;
}

///////////////////////////////////////////////////
//
//	Ждёт прихода сообщения указанное количество миллисекунд (если 0, то ждёт бесконечно)
// Возвращает true если дождалась и false в противном случае.
//
inline static bool receiverWaitForMessage(unsigned long milliseconds = 0) {
   if (milliseconds) {
		unsigned long start = millis();
		while (!vw_rx_done && ((millis() - start) < milliseconds));
		return vw_rx_done;
	}
   while (!vw_rx_done);
   return true; 
}

///////////////////////////////////////////////////
//
//	Получает сообщение в буфер buf.
// Максимальная длина буфера должна находится в *len
// по завершении в *len будет реальная длина полученного сообщения
// возвращает true если сообщение получено нормально
//
inline static bool receiverGetMessage(byte * buf, byte * len) {
   return vw_get_message(buf, len);
}
inline static bool receiverGetMessage(char * s, byte * len) { 
	const byte ln = *len;
	const bool res = receiverGetMessage((byte *) s, len);
	if (ln > *len) *(s + (*len)++) = '\0';
   return res;
}

#endif   // FS1000A_V_h

Пример - передатчик

#include <VirtualWire.h>
#include <FS1000A.h>


void setup(void) {
FS1000A_Init(A2);	// пин передатчика
}

void loop(void) {
   FS1000A_Send("Hello, Dolly!");
   delay (1000);	
}

Пример - приёмник

template <typename T> inline Print & operator << (Print &s, T n) { s.print(n); return s; }

#include <FS1000A_V.h>

void setup(void) {
	Serial.begin(115200);
	Serial << "Fun begins\n";
	receiverInit(A2); // Пин приёмника
	receiverStart(); 
}

void loop(void) {
	if (receiverAvailable()) {
		char s[32];
		byte len = 32;
		receiverGetMessage(s, & len);
		Serial << s << "\n";
	}	
}

 

nicelight
Offline
Зарегистрирован: 20.09.2016

Спаисбо! Попробую) Если не стартанет, буду уже тогда перепиливать собственноручно либу =)

надеюсь, все получится.

nicelight
Offline
Зарегистрирован: 20.09.2016

Удивительно... даже с вашей библиотекой не хотит работать. Как только раскоменчиваю строчку //pixels.sow(); отвечающую за вывод инфы в ленту, так сразу затыкается передача по rf.

Нашел даже другую библиотеку якобы не использующую прерываний. История та же. Как только вывод инфы на ленту, приемник словно засыпает ))

Третью ночь победить не могу.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Похоже, что Ваша библиотека для WS2812 использует и первый, и второй таймеры (так, например, себя ведёт библиотека для TLC5940).

Дайте мне ссылку на Вашу библиотеку, я посмотрю какого ей надо.

nicelight
Offline
Зарегистрирован: 20.09.2016

Самая распространенная для ws2812 

вот описание https://www.adafruit.com/category/168

вот сырцы https://github.com/adafruit/Adafruit_NeoPixel

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

Библиотечка по ходу кушает не малые ресурсы.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Ну, так понятно.

Во-первых, таймеры они не используют, поэтому забудьте наши заморочки с таймерами.

Во-вторых, посмотрите на функцию show (особенно на строку 135 в файле "Adafruit_NeoPixel.cpp") - они там тупо запрещают людбые прерывания, поскольку им нужен точный тайминг. 

Разумеется, приёмник работать не будет, т.к. ему прерывания нужны.

nicelight
Offline
Зарегистрирован: 20.09.2016

спасибо очень дельно!

Что нибудь посоветовать сможете ? 

arduinec
Offline
Зарегистрирован: 01.09.2015

nicelight пишет:

Что нибудь посоветовать сможете ? 

Использовать ленту и передатчик поочерёдно.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

nicelight пишет:

Что нибудь посоветовать сможете ? 

Не могу, потому, что не знаю Вашей задачи. Можно, например, на передатчик взять отдельный маленький контроллер (ATtiny45, например). Или наоборот, на ленту. Но не зная задачи как посоветуешь?

nicelight
Offline
Зарегистрирован: 20.09.2016

менябы устроила хотя бы периодическая отправка получение данных в промежутках между выводом на ленту.. на сколько я понимаю, прерывания снова разрешаютмя по окончании отправки пакета данных на ленту, но у меня пакеты шлютмя так часто, что библиотека получения rf данных не успевает проглотить даже 1 пакет.

Беда)  Если я буду использовать одну ардуину для полно загрузки вывода инфы на RGB ленту, а вторую приконекчу к ней для ретрансляции пакетов с радиоканала, какой тип соединения между ардуинами бнаиболее стабильно будет работать, на ваш взгляд? Там UART тоже живет на прерываниях по ходу... Как на счет I2C или SPI ?

nicelight
Offline
Зарегистрирован: 20.09.2016

Задача получить данные по беспроводному соединению, обработать их и вывести на ленту определенную динамику в зависимости от входящих данных. 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Да, зачем вторая ардуина? На приёмник выше крыши хватит крохотулечки типа ATtiny45. Для связи, опять же я не знаю какие пины у Вас чем заняты, но я бы использовал SPI, а если нет возможности, то программный SPI. Ну, можно сделать полный "самогон" на двух пинах - по сути тот же SPI, но без выбора слэйва - чего его выбирать, когда он один?

Главная ардуина работает с лентой, а когда у неё есть время, соединяется у ATtiny и та её всё. что успело прийти отдаёт. Главна делает что нужно с лентой и опять спрашивает. Ну, и так далее.

arduinec
Offline
Зарегистрирован: 01.09.2015

nicelight пишет:

Задача получить данные по беспроводному соединению, обработать их и вывести на ленту определенную динамику в зависимости от входящих данных. 

И в чём проблема? Получил данные, вывел на ленту и ждёшь опять новых данных.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

arduinec пишет:

И в чём проблема? Получил данные, вывел на ленту и ждёшь опять новых данных.

Я понимаю проблему так: пока выводишь на ленту (с выключенным приёмником) можно пропустить, пришедшие данные.

nicelight
Offline
Зарегистрирован: 20.09.2016

Если я правильно понимаю, проблема в том, что данные вообще перестают гнаться, ибо вывод на ленту довольно часто происходит. Там достаточно динамичные световые эффекты. Программа на свичах написана, получается за одну итерацию цикла выполняется буквально строчек 20 кода (если отбросить приемную часть) и вывод на ленту. 

Мне даже не хватает производительности, ардуина не успевает отрисовать то, что задумано.

nicelight
Offline
Зарегистрирован: 20.09.2016

данные не критично чтобы были пропущены. Они вообще не принимаются со стандартной библиотекой. а с самопалом алгоритм получится такой - после отправки на ленту данных, мне надо обратиться к тиньке и спросить у нее, что там у нас пришло. Тинька будет просто датчик расстояния опрашивать.

ximik_se
Offline
Зарегистрирован: 17.10.2016

Здравствуйте. У меня та же проблема - светодиоды WS2812B и радиомодуль fs1000a (приемник).
Нужно менять анимацию на лету, как только получается управляющий сигнал.
Бился уже 3 ночи над этой проблемо, выявил конфликт библиотек и так же, как и вы застрял...
Вам удалось все же подружить их или это из области фантастики? Смогли победить ситуацию?

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

ximik_se пишет:
выявил конфликт библиотек
А какой именно конфликт для Вас критичен? Если по таймеру, так fs1000a относительно несложно на другой таймер переводится.

ximik_se
Offline
Зарегистрирован: 17.10.2016

ЕвгенийП пишет:

А какой именно конфликт для Вас критичен? Если по таймеру, так fs1000a относительно несложно на другой таймер переводится.

У меня приемник xy-mk-5v, который идет в комплекте с передатчиком fs1000a на 433Мгц.

Я работаю через Adafruit с матрице из светодиодов.

И в процессе выполнения анимации матрицей при подаче сигнала на приемник анимация должна меняться на другую.

Так вот суть конфликта заключается в том, что библиотека Adafruit при выполнении команды отображения изображения на матрице matrix.show() глушит приемник, т.е. его Ардуина в принципе не видит, идет ли с нее сигнал.

Как решить этот  вопрос без привлечения стороннего микроконтроллера я так и не нашел ответа. Потому и спрашиваю здесь, т.к. судя по всему тут разбирается подобная проблема.

nicelight
Offline
Зарегистрирован: 20.09.2016

Здравствуйте. Тема не такая уж длинная, почитайте все сообщения. Проблем может быть две:

Либо работают на одном и том же таймере библиотеки приемника и адафрут, тогда Евгений вам подсказку дал - перевести нужно библиотеку на другой таймер.

Либо проблема в другом.. где то натыкался на инфу, что адафрутовская библиотека вообще запрещает какие либо прерывания во время своей отработки. Тогда тут решение вопроса по пути наименьшего сопротивления - использование двух ардуин. Либо читайте коменты выше. 

ximik_se
Offline
Зарегистрирован: 17.10.2016

Да, я прочитал изначально всю тему. И скачал переделанные файлы. Попробую их потестить. Я изначально сам пришел к двум вариантам решения, но оба они имеют свои минусы и требуют дополнительного железа:

1. (самый хреновый вариант) на передатчике делать условие при котором будет выполняться анимация. Т.е. приемник получает некую переменную, в результате которой разрешает делать анимацию. Если нет переменной, то анимцию делать низя. В этом варианте главный минус - медленная работа анимации, т.к. ее выполнение зависит от сигнала. Да и порой буджет мигание. В общем эта была первая идея. Она мне сразу не понравилась, но все же идея!

 

2. (тот, который здесь представлен, как альтернативный) использовать отдельный микроконтроллер (atTiny85) для работы с радиомодулем и при получении команды, командывать ардуиной через тот же Digital pin (режим работы кнопки).

И вот я все еще питаю надежду, что удасться подружить две библиотеки, чтобы не пришлось городить лишний огород из железяк.

З.Ы.: мне удалось сделать передатчик на atTiny85 с библиотекой VW. А вот приемник что-то работать отказывается... Ночь потратил - не победил.

Ворота
Ворота аватар
Offline
Зарегистрирован: 10.01.2016

Вроде ж выше уже выяснили, что таймеры не при делах. Там проблема в том, что библиотека ws прерывания запрещает. Т.е. одновременно они не живут. Либо надо использовать другую библиотеку, либосерь5зно переделывать эту.

ximik_se
Offline
Зарегистрирован: 17.10.2016

Я использовал ранее FastLED, но она жрет непомерно оператики и к тому же весьма скудна в графической реализации. Так что Adafruit я пока что альтернативы не нашел к сожалению. Она тут лучшая.

Прийдется, видать, все же реализовывать обходной маневр со вторым МК.

nicelight
Offline
Зарегистрирован: 20.09.2016

Смотри на приемные пины, там может быть попутана распиновка ( китайцы косячно маску наложили ). Распиновка в таком порядке: земля, питание, сигнал ( иногда у них попутаны местами питание и сигнал, be carefull ))

nicelight
Offline
Зарегистрирован: 20.09.2016

у меня даже с фастлед библиотекой не запустился RF приемник))

ximik_se
Offline
Зарегистрирован: 17.10.2016

да у меня с распиновкой все гуд.

я сначала тестил на ардуине. на ней скетч отточил - все работает.

потом в сктече меняю пин ресивера на соответствующий у atTiny.

и фигушки...

Самое неудобное, что у atTiny нет возможности просматривать сериал потр.

Я сегодня-завтра подрублю к нему отдеьлный LCD экран и гтогда попытаюсь глянуть. что вообще он ловит.

Тут еще важно понять к какому пину его подключать. Уже вроде все перепробовал.

ximik_se
Offline
Зарегистрирован: 17.10.2016

Я тут по приемнику сделал отдельную тему в форуме:

http://arduino.ru/forum/programmirovanie/pomogite-podruzhit-attiny85-i-xy-mk-5v-priemnik-fs1000a

Гляньте, может какие идеи появятся.

Всем заранее спасибо