#define out_dir 13 // пин отвечающий за направление передачи 1 отправка 0 прием
#define baudrate 9600
#define BYTE unsigned char
long int data, data_len;
char read,test8,len,answ_ok;
char i=0;
char Nstate=0;
uint8_t state_buf[20]; // тут формируется текстовое сообщение отражающее стадию работы
char s[20]; // буфер отправки
char rx_buf[20]; // буфер приема
unsigned short int temp16; //
char* temp8 = (char*)&temp16; // трюк позволяющий обращатся у 16 битной переменной как массив их 2х однобайтных
unsigned long int Pact,PactA,PactB,PactC,temp32;
BYTE* temp88 = (BYTE*)&temp32; // трюк позволяющий обращатся к 32 битной переменной как массив их 4х однобайтных
static os_timer_t esp_timout; // глобально объявим таймер esp_timer
// sensors_param.cfgdes[0] резерв
//***************************-=Вычисление CRC16=-**************************
unsigned short int CRC16(char *buf, char len)
{ char pos,i;
short int crc = 0xFFFF;
for (pos = 0; pos < len; pos++)
{
crc ^= (short int)buf[pos];
for (i=8; i!= 0; i--)
{
if ((crc & 0x0001) != 0)
{
crc = (crc>>1)&0x7fff;
crc ^= 0xA001;
}
else
crc = (crc>>1)&0x7fff;
}
}
// Помните, что младший и старший байты поменяны местами, используйте соответственно (или переворачивайте)
return crc;
}
//***************************-=Чтение данных=-**************************
// задача загрузить в массив ответ счеткика в переменно len хранится ожидаемая длинна ответа
// после получение ответа заданной длинны проверка CRC ответа
// также нужно реализовать таймаут ожидания ответа - пока не реализовано
read_data(void)
{
WRITE_PERI_REG(UART_INT_CLR(UART0), UART_RXFIFO_FULL_INT_CLR);
while (READ_PERI_REG(UART_STATUS(UART0)) & (UART_RXFIFO_CNT << UART_RXFIFO_CNT_S))
{
WRITE_PERI_REG(0X60000914, 0x73); //WTD
rx_buf= READ_PERI_REG(UART_FIFO(UART0)) & 0xFF; // перекидываем данные в свой массив
i++;
if (i<len)
{
answ_ok=0; // длинна ответа не достаточно
}
if (i==len)
{
temp16=CRC16(rx_buf,len-2); // вычисление CRC ответа
if ((temp8[0]==rx_buf[len-2])&&(temp8[1]==rx_buf[len-1]))
{answ_ok=1; // ошибок нет crc верное
}
else {answ_ok=2; // crc не совпадает
};
}
if (i>len)
{
answ_ok=i+10; // ответ длинее
}
}
}
//***************************-=Переключение RS485 на прием=-**************************
void switchBackDir() // switches direction back to receiving
{
digitalWrite(13,0);
}
//***************************-=Запустить таймер переключения напрвыления приема-передачи=-**************************
void set_timeout(char Nb) // switches direction back to receiving
{
data_len=(Nb*10000)/baudrate+1;
// запуск таймера:
os_timer_disarm(&esp_timout);
os_timer_setfn(&esp_timout, (os_timer_func_t *)switchBackDir, NULL); // switchBackDir -функцию, которую нужно вызвать по таймеру.
os_timer_arm(&esp_timout,data_len, 0); // 1000 миллисекунд. 1 - многократно. 0 -однократно.
}
//***************************-=Тест связи со счетчиком=-**************************
void cmd1(void)
{
answ_ok=0; // очистка флага анализа ответа
digitalWrite(13,1); // включить режим передачи на RS485
strcpy(state_buf, "Соединение..."); // Статус устройства
s[0]=0x03; // адрес счетчика
s[1]=0x00; // команда
temp16=CRC16(s,2); // вычисление CRC
s[2]=temp8[0]; // temp16 является массивом их 2х элементов temp8
s[3]=temp8[1];
uart0_tx_buffer(s,4); // отправить данные
set_timeout(4); // запустить таймер на переключение шины на прием
i=0; // счетчик полученных байт
len=4; // ожидаемая длинна ответа
}
//***************************-=Открытие порта, ввод пароля=-**************************
void cmdPass(void)
{
answ_ok=0;
digitalWrite(out_dir,1); // включить режим передачи на RS485
strcpy(state_buf, "login");
s[0]=0x03; // адрес счетчика
s[1]=0x01; // команда
s[2]=0x02; // уровень доступа
s[3]=0x02; // пароль
s[4]=0x02;
s[5]=0x02;
s[6]=0x02;
s[7]=0x02;
s[8]=0x02;
temp16=CRC16(s,9);
s[9]=temp8[0]; // temp16 является массивом их 2х элементов temp8
s[10]=temp8[1];
uart0_tx_buffer(s,11);
set_timeout(11); // запустить таймер на переключение шины на прием
i=0; // счетчик полученных байт
len=4; // ожидаемая длинна ответа
}
//***************************-=Чтение активной мощности=-**************************
void cmdW(void)
{
answ_ok=0;
digitalWrite(13,1); // включить режим передачи на RS485
s[0]=0x03;
s[1]=0x08; // команда
s[2]=0x16; // субкоманда
s[3]=0x00; // BWI 00 активная мощность 04 реативная мощность
temp16=CRC16(s,4);
s[4]=temp8[0]; // temp16 является массивом их 2х элементов temp8
s[5]=temp8[1];
uart0_tx_buffer(s,6);
set_timeout(6);
i=0; // счетчик полученных байт
len=15; // ожидаемая длинна ответа
// lcd_putchar('A');
// temp88[0]=rx_buffer[5];
// temp88[1]=rx_buffer[6];
// temp88[2]=(rx_buffer[4]&0b00111111);
// temp88[3]=0;
// lcd_putchar('B');
// temp88[0]=rx_buffer[8];
// temp88[1]=rx_buffer[9];
// temp88[2]=(rx_buffer[7]&0b00111111);
// temp88[3]=0;
//lcd_putchar('C');
// temp88[0]=rx_buffer[11];
// temp88[1]=rx_buffer[12];
// temp88[2]=(rx_buffer[10]&0b00111111);
// temp88[3]=0;
}
void ICACHE_FLASH_ATTR
startfunc(){
uart_init(BIT_RATE_9600);
ETS_UART_INTR_ATTACH(read_data, NULL);
strcpy(state_buf, "Запуск...");
// выполняется один раз при старте модуля.
}
void ICACHE_FLASH_ATTR
timerfunc(uint32_t timersrc) {
// выполнение кода каждую 1 секунду
switch (Nstate) // анализ текущей стадии работы
{
case 0:
cmd1(); // тест связи
Nstate++; // следующий шаг
break;
case 1:
if (answ_ok==1)
{
cmdPass(); //ввод пароля
Nstate++; // следующий шаг
}
break;
case 2:
if (answ_ok==1)
{
strcpy(state_buf, "Логин принят");
cmdW(); // запросить данные о мощности
Nstate++; // следующий шаг
}
break;
case 3:
if (answ_ok==1)
{Nstate++;
strcpy(state_buf, "Мощность считана");
temp88[0]=rx_buf[2];
temp88[1]=rx_buf[3];
temp88[2]=(rx_buf[1]&0b00111111);
temp88[3]=0;
Pact=temp32;
}
break;
case 4:
break;
case 5:
break;
case 6:
break;
case 7:
break;
case 8:
break;
case 9:
break;
case 10:
break;
case 11:
break;
case 12:
break;
case 13:
break;
case 14:
break;
case 15:
break;
case 16:
break;
}
//if(timersrc%10==5)
// {
// }
}
// вывод отладочных данных
void webfunc(char *pbuf) {
os_sprintf(HTTPBUFF,"Merkuriy<br>"); // вывод данных на главной модуля
os_sprintf(HTTPBUFF,"Ответ%d<br>",answ_ok);
os_sprintf(HTTPBUFF,state_buf);
os_sprintf(HTTPBUFF,"<br>Шаг%d<br>",Nstate);
os_sprintf(HTTPBUFF,"Ответ%02x%x%x%x<br>",rx_buf[0],rx_buf[1],rx_buf[2],rx_buf[3]);
os_sprintf(HTTPBUFF,"Мощность%d<br>",Pact);
}