qczek lrs – 433mhz 1w (30dbm) lora rc link with telemetry - новая народная?
Так… Заняться тоже что ли. Все равно погода не летная. Есть самописный драйвер по SSD1306(можно рисовать и текст выводить) и проект “меню” аля ОС для AVR. Все на С++ без ардуиновский билиотек 😃. Я упоротый 😃 Можно и меню настроек сделать для QCZEK
Так… Заняться тоже что ли. Все равно погода не летная. Есть самописный драйвер по SSD1306 и проект “меню” аля ОС для AVR. Все на С++ без ардуиновский билиотек 😃. Я упоротый 😃
Да я взял текстовую либу для 1306, она ничего не весит, если один шрифт особенно заюзать… сравните со своей кстати, интересно)
она ничего не весит, если один шрифт особенно заюзать
Да. Я уже глянул вчера. Много весит mavlink либа. Не хочется еще с этим разбираться(могу упороться случайно). В теории можно получить признак режима настройки(правда там скорость другая) и рисовать меню. У меня кстати 128х64 + есть какой-то цветной дисплей под SPI. Хмм… Закиньте свои наработки в группу на rcgroups. Думаю там прибавят энтузиазма 😃
Закиньте свои наработки в группу на rcgroups. Думаю там прибавят энтузиазма 😃
Пока неумею, если получится - закиньте вы)
А можно крайний вариант скетча? Тоже хочется такое к ретранслятору прикрутить. Скорее всего буду перепиливать под ч/б дисплей от нокии, мне кажется, на солнце так лучше видно будет…
#include <Wire.h>
#include "SSD1306Ascii.h"
#include "SSD1306AsciiWire.h"
#include <mavlink.h>
#include <EEPROM.h>
#define I2C_ADDRESS 0x3C
#define RST_PIN -1
SSD1306AsciiWire oled;
#define MAV_TIMEOUT 5000 //mavlink timeout
#define SERIAL_SPEED 9600 //9600 for sbus, 57600 for cppm
#define DEBUG
mavlink_message_t msg;
mavlink_status_t status;
//mavlink_global_position
int32_t alt, relative_alt;
int16_t vx, vy, vz;
uint16_t hdg;
//__mavlink_sys_status_t
int8_t battery_remaining;
uint16_t current_battery, voltage_battery, cpu_load, drop_rate_comm;
//mavlink_gps_raw_int_t
int32_t lat, lon, gps_alt;
uint8_t satellites_visible, fix_type;
uint16_t cog, vel;
//mavlink_rc_channels_raw_t
uint8_t rssi;
//oth
uint8_t flag, eeprom_flag = 0;
uint32_t time_flag;
//------------------------------------------------------------------------------
void setup() {
Wire.begin();
Wire.setClock(400000L);
oled.begin(&Adafruit128x32, I2C_ADDRESS);
display_wait();
//
Serial.begin(SERIAL_SPEED);
//
time_flag = millis();
}
//------------------------------------------------------------------------------
void loop() {
while(Serial.available()) {
uint8_t c= Serial.read();
if(mavlink_parse_char(MAVLINK_COMM_0, c, &msg, &status)) {
flag = 0;
switch(msg.msgid) {
case MAVLINK_MSG_ID_HEARTBEAT: {
break;
}
case MAVLINK_MSG_ID_GLOBAL_POSITION_INT: {
mavlink_global_position_int_t packet;
mavlink_msg_global_position_int_decode(&msg, &packet);
if(packet.hdg == 65535) packet.hdg = 0;
//if(lat != packet.lat) { lat = packet.lat; set_flag(); }
//if(lon != packet.lon) { lon = packet.lon; set_flag(); }
//if(alt != packet.alt) { alt = packet.alt; set_flag(); }
if(relative_alt != packet.relative_alt) { relative_alt = packet.relative_alt; set_flag(); }
//if(vx != packet.vx) { vx = packet.vx; set_flag(); }
//if(vy != packet.vy) { vy = packet.vy; set_flag(); }
//if(vz != packet.vz) { vz = packet.vz; set_flag(); }
if(hdg != packet.hdg) { hdg = packet.hdg; set_flag(); }
break;
}
case MAVLINK_MSG_ID_SYS_STATUS: {
__mavlink_sys_status_t packet;
mavlink_msg_sys_status_decode(&msg, &packet);
if(battery_remaining != packet.battery_remaining && packet.battery_remaining >= 0) { battery_remaining = packet.battery_remaining; set_flag(); }
if(voltage_battery != packet.voltage_battery && packet.voltage_battery != 65535) { voltage_battery = packet.voltage_battery; set_flag(); }
if(current_battery != packet.current_battery) { current_battery = packet.current_battery; set_flag(); }
if(cpu_load != packet.load) { cpu_load = packet.load; set_flag(); }
if(drop_rate_comm != packet.drop_rate_comm) { drop_rate_comm = packet.drop_rate_comm; set_flag(); }
break;
}
case MAVLINK_MSG_ID_ATTITUDE: {
break;
}
case MAVLINK_MSG_ID_GPS_GLOBAL_ORIGIN: {
break;
}
case MAVLINK_MSG_ID_RC_CHANNELS_RAW: {
__mavlink_rc_channels_raw_t packet;
mavlink_msg_rc_channels_raw_decode(&msg, &packet);
if(rssi != packet.rssi) { rssi = packet.rssi; set_flag(); }
break;
}
case MAVLINK_MSG_ID_VFR_HUD: {
break;
}
case MAVLINK_MSG_ID_GPS_RAW_INT: {
__mavlink_gps_raw_int_t packet;
mavlink_msg_gps_raw_int_decode(&msg, &packet);
if(packet.cog == 65535) packet.cog = 0;
if(packet.vel == 65535) packet.vel = 0;
if(packet.alt == 65535) packet.alt = 0;
if(lat != packet.lat) { lat = packet.lat; set_flag(); }
if(lon != packet.lon) { lon = packet.lon; set_flag(); }
//if(gps_alt != packet.alt) { gps_alt = packet.alt; set_flag(); }
if(vel != packet.vel) { vel = packet.vel; set_flag(); }
if(cog != packet.cog) { cog = packet.cog; set_flag(); }
if(fix_type != packet.fix_type) { fix_type = packet.fix_type; set_flag(); }
if(satellites_visible != packet.satellites_visible) { satellites_visible = packet.satellites_visible; set_flag(); }
break;
}
default: {
#ifdef DEBUG
Serial.println(msg.msgid); //see unused packet types
#endif
break;
}
}//switch
if(flag == 1) {
display_data();
}//print flag
else {
no_data();
}
}//if mavlink_parse_char
}//while serial available
no_data(); //check no serial input data fuction
}
void set_flag() {
flag = 1;
eeprom_flag = 0;
time_flag = millis();
}
void display_wait() {
oled.setFont(font8x8);
oled.set2X();
oled.clear();
oled.println("WAIT FOR");
oled.println("MAVLINK");
oled.set1X();
oled.setFont(font5x7);
}
void display_data() {
oled.clear();
printL(lat); //gps
oled.print(" ");
printL(lon);
oled.println();
oled.println((String)"S"+satellites_visible+(String)" F"+fix_type+(String)" R"+map(rssi,0,255,0,100)+(String)"% L"+cpu_load/10+(String)"% E"+drop_rate_comm/100+(String)"%");
oled.println((String)"H"+hdg+(String)" S"+(uint8_t)(vel/100*3.6)+(String)"k A"+relative_alt/1000+(String)"m");
oled.println(current_battery/100.0+(String)"A "+voltage_battery/1000.0+(String)"v R"+battery_remaining+(String)"%");
}
void printL(int32_t degE7) {
// Extract and print negative sign
if (degE7 < 0) {
degE7 = -degE7;
oled.print( '-' );
}
// Whole degrees
int32_t deg = degE7 / 10000000L;
oled.print( deg );
oled.print( '.' );
// Get fractional degrees
degE7 -= deg*10000000L;
// Print leading zeroes, if needed
int32_t factor = 1000000L;
while ((degE7 < factor) && (factor > 1L)){
oled.print( '0' );
factor /= 10L;
}
// Print fractional degrees
oled.print( degE7 );
}
void no_data() {
if((millis() - time_flag) > MAV_TIMEOUT ) { //no mavlink data at 2sec
#ifdef DEBUG
Serial.println((String)"LOST MAVLINK DATA");
#endif
display_wait();
delay(300);
if(eeprom_flag == 0 && lat != 0 && lon != 0 && fix_type > 1) { //if gps coordinates present, save it
#ifdef DEBUG
Serial.println("save..");
#endif
EEPROM_int32_write(5, lat);
EEPROM_int32_write(16, lon);
EEPROM.write(30, satellites_visible);
EEPROM.write(32, fix_type);
EEPROM.write(34, cpu_load);
EEPROM.write(40, drop_rate_comm);
EEPROM.write(46, hdg);
EEPROM.write(52, vel);
EEPROM_int32_write(56, relative_alt);
EEPROM.write(66, current_battery);
EEPROM.write(72, voltage_battery);
EEPROM.write(74, battery_remaining);
EEPROM.write(76, rssi);
eeprom_flag = 1;
} else { //no fresh data on mavlink, read from memory
#ifdef DEBUG
Serial.println("read..");
#endif
lat = EEPROM_int32_read(5);
lon = EEPROM_int32_read(16);
satellites_visible = EEPROM.read(30);
fix_type = EEPROM.read(32);
cpu_load = EEPROM.read(34);
drop_rate_comm = EEPROM.read(40);
hdg = EEPROM.read(46);
vel = EEPROM.read(52);
relative_alt = EEPROM_int32_read(56);
current_battery = EEPROM.read(66);
voltage_battery = EEPROM.read(72);
battery_remaining = EEPROM.read(74);
rssi = EEPROM.read(76);
eeprom_flag = 1;
}
display_data();
time_flag = millis();
}
}
int32_t EEPROM_int32_read(int addr) // чтение из EEPROM 4 байта unsigned long
{
byte raw[4];
for(byte i = 0; i < 4; i++) raw[i] = EEPROM.read(addr+i);
int32_t &data = (int32_t&)raw;
return data;
}
//*****************************************************************
void EEPROM_int32_write(int addr, int32_t data) // запись в EEPROM 4 байта unsigned long
{
byte raw[4];
(int32_t&)raw = data;
for(byte i = 0; i < 4; i++) EEPROM.write(addr+i, raw[i]);
}
Пока неумею, если получится - закиньте вы)
Готово. Я думаю это увидит автор QLRS
Подскажите, какие значения min\max выставить в OSD в этом случае ?
в режиме snr у меня предварительно вышло:
set rssi_min = 25
set rssi_max = 30
у кого как?
Код:
Переделал под ч/б дисплей 5110, оставил то, что мне нужно. Работает. Завтра прикручу к ретранслятору. Спасибо за код.
Хотел еще адаптер sd карт прикрутить, чтоб логировать на карточку все, что там через мавлинк сыпется, но с моей криворукостью у 328 про мини не хватает на это памяти… Мдя…
Класс!) Рад, что кому то пригодилось.
Про логгирование думал, минипро доедет и попробую. Но вытянуть fat наверное нехватит памяти никак.
Подумываю на пробу взять модули на 868.На борту видео передатчик под 900Мгц. Уживутся ли они? Не будут ли мешать друг другу по частотам?
Опробовал скетч дисплея на pro micro, a32u4 где чип. Понадобилось Serial сменить на Serial1 и все. Теперь корпус закрывается и вид изделия законченный)
Жду раму… едет через Казахстан на оленях, далее сборка и испытания qlrs.
Что касается трекера - закажу на днях серву и AK8975
В скетч влезает точно поключение к нему и чтение heading в degrees
Скетч использует 19614 байт (68%) памяти устройства. Всего доступно 28672 байт.
Глобальные переменные используют 1649 байт (64%) динамической памяти, оставляя 911 байт для локальных переменных. Максимум: 2560 байт.
Доделал и установил мавлинковский модуль с дисплеем на ретранслятор.
Добавил два вольтметра, для мониторинга напряжения на батареях ретранслятора.
Добавил пищалку (12A05). Бузер слега попискивает (раз в 7 секунд) при пропадании мавлинка и нудно пищит при снижении напряжения батарей ретранслятора. Сделал автоматическое включение подсветки дисплея при снижении освещенности.
стилизовать бы его под военное устройство времен СССР 😃
стилизовать бы его под военное устройство времен СССР
можно и под СССР. а можно и под стимпанк…)))
… Допиливать еще есть что, но уже можно повторять. …
Давно не попадались настолько конкретные и полезные посты.
Спасибо…
может по армингу аппарата запоминать “дом”, чтоб исключить человеческий фактор
угу, вполне себе вариант.
Не поленитесь вынести это в дневник отдельной темой, чтобы не терялось и развитие видно было бы коллегам, ибо полезная штука похоже получилось.
.
Не поленитесь вынести это в дневник отдельной темой, чтобы не терялось и развитие видно было бы коллегам, ибо полезная штука похоже получилось.
Давайте как компас приедет, трекер опробую
Давайте как компас приедет, трекер опробую
с трекером было бы вообще круто.
Мне все таки хочется нормального логирования на земле. Чтоб хватало памяти под все хотелки - заказал MEGA 2560 в миниформате (38x55 мм) - там памяти больше в 4 раза. Часы реального времени на DS3231 и и адаптер под карточки сд валялись в загажнике - сейчас пишу логгер. Потом нужно будет под мегу переделать.
Во вложении положил скетч под нокиевский экран 5110. Ардуина - Pro Mini 328 - я использовал на 3.3V,
чтоб вывозило пищалку напрямую - держит ток до 40 ма на выходах. Соединения - как на фото в посте выше. Резисторы в делителях вольтметров - нижние 820 ом - верхние 2.8 к (это под измеряемые напряжения до 9 вольт). Внешнюю понижайку на 3.3 можно не делать (я делал т.к. планировал подключать адаптер SD) и подать питание 5-8 вольт на вход raw.
Если в эту ардуину (про мини/микро) не будет лезть что то, можно параллельно рядом такую же поставить)
Давайте как компас приедет, трекер опробую
Соблазнительно.
Точно отдельная тема для дневника получается…
Чтоб хватало памяти под все хотелки - заказал MEGA 2560 в миниформате
Если с трекером, то можно и большую ставить, место будет.
Должно влезть в любую от 328 и выше, либа компаса и получение своего hdg точно лезет с хорошим запасом, вопрос в расчете азимута между двумя координатами в deg… инфы насобирал, буду пробовать, но не думаю что там большой объем займет.
Вот проект был трекера ,возможно пригодится информация code.google.com/archive/p/opendiyantracker/