Skocz do zawartości

blockchain

Użytkownicy
  • Zawartość

    5
  • Rejestracja

  • Ostatnio

Informacje

  • Płeć
    Mężczyzna

Osiągnięcia użytkownika blockchain

Młodszy odkrywca

Młodszy odkrywca (3/19)

  • Za 5 postów
  • To już rok!
  • Młodszy Juror

Odznaki

0

Reputacja

  1. Wciąż zależy mi na rozwiązaniu problemu. Mogę zapłacić 1000zł.
  2. Dzień dobry, Z problemem borykam się już długi czas, ale utknąłem i obawiam się że moja wiedza jest po prostu niewystarczająca, by wszystko zrozumieć - szukam pomocy. Usiłuję skomunikować ze sobą nadajnik Silicon Labs Si4010 oraz wariometr Flymaster GPS SD (jego odbiornik to Si4355 ) za pomocą sygnału radiowego. Chcę wysłać odczyt temperatury z zewnętrznego czujnika (termometru zamontowanego na szycie powłoki balonu na ogrzane powietrze). Urządzenie nie pokazuje sygnału nadajnika w swoim interfejsie najprawdopodobniej z powodu niepoprawnego sygnału. Sygnał, który muszę wysłać został mi opisany tak: [PREAMBLE][PREAMBLE][PACK_ID][DATA][CRC] 4 bytes for preamble + 2 for syncword + 2 for datatype and ID + 2 data + 1 for CRC (w pierwszej linijce producent najwyraźniej zapomniał wpisać syncword) Wydaje mi się, że 80% tego sygnału mam przygotowane poprawnie, ale nie rozumiem funkcji generującej sumę kontrolną CRC. Od producenta wariometru dostałem skrawki kodu które mają mi pomóc: RF CODE Kod nadajnika jest dostępny na GitLab - plik keyfob_demo_2_main.c. Jest to zmodyfikowany przykład kodu nadajnika wysyłającego numer naciśniętego przycisku. A więc po kolei to, co udało mi się zrobić na podstawie wskazań z RF CODE: PREAMBLE = 0xAA 4 bajty PREAMBLE = 0xAAAA 0xAAAA SYNCWORD = 0xD42D PACKID = 0x1FFF Wartości powyżej na podstawie przykładowego kodu od producenta — void FmInvertEndian(UINT16 *pwLittleEndian) { UINT8 hold; UINT8 *ptr; ptr = (UINT8*) pwLittleEndian; hold = ptr[1]; ptr[1] = ptr[0]; ptr[0] = hold; } #define RF_Preamble 0xAAAA #define RF_SyncroWord 0xD42D // i16PacketType - sensor type // i16ID - serial number // TAS packet type is 5 (0x5) void InitRFPackage(UINT16 i16PacketType, UINT16 i16ID) // InitRFPackage(5,i16ID) { UINT8 *tmp; // Set Preamble and SyncroWord g_aRFPAcket[PREAMBLE_1] = RF_Preamble; // 0xAAAA g_aRFPAcket[PREAMBLE_2] = RF_Preamble; // 0xAAAA g_aRFPAcket[SYNCWORD_1] = RF_SyncroWord; // 0xD42D g_aRFPAcket[PACK_ID] = i16PacketType & 0x7; // 0x5 & 0x7 -> 0x5 i16ID &= 0x1FFF; FmInvertEndian(&i16ID); tmp = (UINT8*) &i16ID; tmp[0] >>= 3; g_aRFPAcket[PACK_ID] |=i16ID; // 0x5 |= 0x1FFF -> 0x1FFF } — DATA = 0xAAAA (przykładowa wartość temperatury, nie mam pojęcia jak zostanie odczytana w urządzeniu) CRC - 0x00 - placeholder, bo nie wiem jak jest obliczana zarówno w przykładowym kodzie od producenta wariometru jak i w kodzie z którego korzystam — void FillRFPacket() { UINT8 i8DataIndex; UINT16 ai16TempBuff[2]; // maximum size of array is 3 (0,1,2) UINT8 *ptri8; InitRFPackage(5,g_i16SerialNumber); ptri8= (UINT8*) (g_aRFPAcket + HDRSIZE ); // co to jest HDRSIZE? ai16TempBuff[0] = g_aRFPAcket[PACK_ID]; // = 0x1FFF // ai16TempBuff = [0x1FFF] for(i8DataIndex=0; i8DataIndex < g_i16BufferIndex; i8DataIndex++) // co to jest g_i16BufferIndex? { ai16TempBuff[1] = g_aRFBuffer[i8DataIndex]; memcpy(ptri8, (UINT8*) (ai16TempBuff+1), sizeof(UINT16) ); ptri8 += sizeof(UINT16); *ptri8 = calculate_CRC((UINT8*) ai16TempBuff,(2*sizeof(UINT16))); ptri8++; } } UINT8 calculate_CRC(UINT8 *ptrTemp,UINT8 i8Lenght) { UINT8 i8CRC=0,i8; for(i8 = 0; i8 < i8Lenght; i8++) // Last byte is CRC byte { i8CRC ^= ptrTemp[i8]; } return(i8CRC); } --- Oraz kod odpowiadający za przygotowanie sygnału do wysłania: — void PutOnRFBuffer(UINT16 i16ValueToSend) { if(g_i16BufferIndex>RF_BUFFER_SIZE) return; g_aRFBuffer[g_i16BufferIndex]=i16ValueToSend; g_i16BufferIndex++; } // Prepare data to be sent #define THERMISTOR_ID_MASK 0xC000 // thermistor data id void PrepareToSend(UINT16 i16DataType, UINT16 i16DataValue) { // Mask Data i16DataValue &= 0x3FFF; // clean mask i16DataValue |= THERMISTOR_ID_MASK; PutOnRFBuffer(i16DataValue); } — Podsumowując, z tego co rozumiem ramka sygnału powinna wyglądać tak: 0xAAAA 0xAAAA 0xD42D 0x1FFF 0xAAAA 0x00 Przekształcając to na kod, który napisałem przerabiając przykładowy program od Silicon Labs: — void vPacketAssemble (void) { BYTE i; pbFrameHead = abFrame ; bFrameSize = bFrameSize_c; for (i=0;i<bPreambleSize_c;i++) // bPreambleSize_c = 4 { abFrame[i] = bPreamble; } abFrame[bFrameSize_c - 9] = bSync1_c; // 0x2D abFrame[bFrameSize_c - 8] = bSync2_c; // 0xD4 abFrame[bFrameSize_c - 7] = 0x5; // TAS packet type abFrame[bFrameSize_c - 6] = 0x1F; // example ID abFrame[bFrameSize_c - 5] = 0xFF; // example ID abFrame[bFrameSize_c - 4] = 0xAA; // example data abFrame[bFrameSize_c - 3] = 0xAA; // example data abFrame[bFrameSize_c - 2] = 0; //CRC, see function vCalculateCrc below abFrame[bFrameSize_c - 1] = 0; //CRC, see function vCalculateCrc below vCalculateCrc(); return; } //-------------------------------------------------------------- //Calculate CRC and write in the frame buffer //Bit pattern used (1)1000 0000 0000 0101, X16+X15+X2+1 void vCalculateCrc(void) { BYTE i,j; WORD wCrc; wCrc = 0xffff; for(j = bPayloadStartIndex_c;j<bPayloadStartIndex_c + bPayloadSize_c;j++) { wCrc = wCrc ^ ((WORD)abFrame[j]<<8); for (i = 8; i != 0; i--) { if (wCrc & 0x8000) { wCrc = (wCrc << 1) ^ 0x8005; } else { wCrc <<= 1; } } } //----------------------------------------------------------------- //Write CRC in frame abFrame[bFrameSize_c - 2] = ((BYTE*)&wCrc)[0]; abFrame[bFrameSize_c - 1] = ((BYTE*)&wCrc)[1]; return; } --- Wysyłam to, ale niestety żadne wykryte urządzenie nie pojawia w odbiorniku. Nie bardzo wiem co może być przyczyną. PS. Jestem również w stanie "odpłacić się" finansowo lub lotem balonem dla jednej osoby w Krakowie za dokończenie rozwiązania i poprawne skomunikowanie urządzeń. Mieszkam w Krakowie, posiadam devkit Silicon Labs oraz wariometr.
  3. Dzięki! Rzeczywiście, nie pomyślałem o możliwościach Arduino. Po przeczytaniu kilku blogpostów o oszczędzaniu energii myślę, że dobrze napisany program powinien wystarczyć.
  4. Cały układ ma wysłać wartość pomiaru radiowo przy pomocy nadajnika RF Silicon Labs Si4010. Odpowiedni sygnał cyfrowy dla nadajnika zostanie przygotowany przez Arduino, LM35 będzie podawać temperatury na analogowe wejście. Szkopuł polega na tym, że cały układ będzie zasilany bateryjnie i powinien działać najlepiej miesiącami bez wymiany baterii (zakładam max 4xAA lub 1x 9V, tak więc Vcc będzie pomiędzy 6 a 9v). Nie może być uruchamiany i wyłączany ręcznie, tak więc pobór prądu przez Arduino i nadawanie fal radiowych będą zbyt duże na ciągłe działanie. Powinien się uruchamiać od temperatury około 70 stopni. Czas uruchomienia układu szacuję na średnio 10h miesięcznie. Wstyd się przyznać, ale z wykształcenia jestem elektronikiem, jednak mój ostatni kontakt z "branżą" miał miejsce dosyć dawno i sporo już zapomniałem. Płytki PCB zaprojektować, wyprasować/zamówić i polutować potrafię 🙂
  5. Hej, Planuję budowę układu, który ma się uruchamiać dopiero od pewnej temperatury. Termometr LM35 ma być na stałe podłączony do zasilania, a po osiągnięciu danej temperatury (np. na wyjściu jest 500mV) zostaje uruchomiony cały układ. Jak nazywają się takie przekaźniki, które zamkną obwód zasilania dla układu przy odpowiednim poziomie napięcia? Co wpisać w Google? Dzięki
×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.