diff --git a/README.md b/README.md index db35b64..bc46d61 100644 --- a/README.md +++ b/README.md @@ -18,12 +18,13 @@ ![IMG_20250212_190518](https://github.com/user-attachments/assets/dd87b7de-c97d-4ecb-ab24-f5a34b849914) -The receiver currently converts the raw temperature reading to °C and -displays it with the RSSI value and CRC result on a nice IPS TFT display. -It responds to the transmitter as kind of ack with the RSSI, which -might be useful do to some sort of power management in the transmitter. -The transmitter waits for this response with a timeout so it won't be blocked -and comsume a lot of power just because there is no response coming back. +The receiver currently converts the raw temperature reading to °C and displays +it with the RSSI value, CRC result and transmitter output power on a nice IPS +TFT display. It responds to the transmitter as kind of ack with the RSSI, which +is used for some very basic power management in the transmitter, reducing the +supply current from 45 mA down to ~15 mA. The transmitter waits for this +response with a timeout so it won't be blocked and comsume a lot of power just +because there is no response coming back. ## Range diff --git a/avrrfm.c b/avrrfm.c index 0efbdf2..abb8326 100644 --- a/avrrfm.c +++ b/avrrfm.c @@ -179,7 +179,8 @@ */ static void transmitTemp(uint8_t node) { uint16_t temp = readTSens(); - uint8_t payload[] = {(temp >> 8), temp & 0x00ff}; + uint8_t power = getOutputPower(); + uint8_t payload[] = {(temp >> 8), temp & 0x00ff, power}; transmitPayload(payload, sizeof (payload), node); // printString("Transmitted\r\n"); } @@ -194,28 +195,31 @@ if (len > 0) { // receiver RSSI int8_t rssi = divRoundNearest(response[0], 2); - printUint(rssi); + setOutputPower(rssi); } } /** * Converts the raw temperature to °C and lets it float around the display. * - * @param raw temperature + * @param rssi RSSI value + * @param crc CRC result + * @param temp temperature + info */ -static void displayTemp(uint8_t rssi, bool crc, uint16_t raw) { +static void displayTemp(uint8_t rssi, bool crc, Temperature *temp) { uint8_t _rssi = divRoundNearest(rssi, 2); - int16_t tempx10 = convertTSens(raw); - div_t temp = div(tempx10, 10); + int16_t tempx10 = convertTSens(temp->raw); + div_t tdiv = div(tempx10, 10); - char buf[32]; + char buf[42]; - snprintf(buf, sizeof (buf), "RSSI: %4d dBm, CRC: %d", -_rssi, crc); + snprintf(buf, sizeof (buf), "RSSI: %4d dBm, CRC: %d, PA: %+3d dBm", + -_rssi, crc, -18 + (temp->power & 0x1f)); const __flash Font *unifont = &unifontFont; writeString(0, 0, unifont, buf, WHITE, BLACK); snprintf(buf, sizeof (buf), "%c%d.%d°", tempx10 < 0 ? '-' : ' ', - abs(temp.quot), abs(temp.rem)); + abs(tdiv.quot), abs(tdiv.rem)); const __flash Font *dejaVu = &dejaVuFont; if (width > 0) fillArea(xo, yo, width, dejaVu->height, WHITE); @@ -230,18 +234,19 @@ } /** - * Reads and returns the raw temperature. + * Reads and returns the raw temperature + other info. * - * @return raw temp + * @return temperature + info */ -static uint16_t readTemp(void) { - uint8_t payload[2]; +static Temperature readTemp(void) { + uint8_t payload[3]; readPayload(payload, sizeof (payload)); - uint16_t raw = 0; - raw |= payload[0] << 8; - raw |= payload[1]; + Temperature temp = {0}; + temp.raw |= payload[0] << 8; + temp.raw |= payload[1]; + temp.power = payload[2]; - return raw; + return temp; } int main(void) { @@ -292,14 +297,14 @@ PayloadFlags flags = payloadReady(); if (flags.ready) { uint8_t rssi = readRssi(); - uint16_t raw = readTemp(); + Temperature temp = readTemp(); // TODO delay? _delay_ms(10); uint8_t payload[] = {rssi}; transmitPayload(payload, sizeof (payload), NODE2); - displayTemp(rssi, flags.crc, raw); + displayTemp(rssi, flags.crc, &temp); startReceive(); } } diff --git a/rfm69.c b/rfm69.c index 5ad3515..637aece 100644 --- a/rfm69.c +++ b/rfm69.c @@ -183,6 +183,20 @@ printString("Radio init done\r\n"); } +void setOutputPower(uint8_t rssi) { + uint8_t pa = 0x40; // -18 dBm with PA1 + if (rssi > 0 && rssi <= 40) pa += 16; + if (rssi > 40 && rssi <= 60) pa += 21; + if (rssi > 60 && rssi <= 90) pa += 26; + if (rssi > 90) pa += 31; + + regWrite(PA_LEVEL, pa); +} + +uint8_t getOutputPower(void) { + return regRead(PA_LEVEL); +} + void timeoutRadio(void) { irqFlags1 |= (1 << 2); } @@ -248,6 +262,8 @@ setMode(MODE_STDBY); if (timeout) { + regWrite(PA_LEVEL, 0x5f); + return 0; } diff --git a/rfm69.h b/rfm69.h index e6b2d96..da3353b 100644 --- a/rfm69.h +++ b/rfm69.h @@ -78,12 +78,43 @@ #define CAST_ADDRESS 0x84 /** + * Flags for "payload ready" event. + */ +typedef struct { + bool ready; + bool crc; +} PayloadFlags; + +/** + * Temperature read from transmitter including + * additional information. + */ +typedef struct { + uint16_t raw; + uint8_t power; +} Temperature; + +/** * Initializes the radio module with the given carrier frequency in kilohertz * and node address. */ void initRadio(uint64_t freq, uint8_t node); /** + * Sets the output power based on the given receiver RSSI. + * + * @param rssi + */ +void setOutputPower(uint8_t rssi); + +/** + * Returns the current output power setting. + * + * @return ouput power + */ +uint8_t getOutputPower(void); + +/** * Indicates a timeout. */ void timeoutRadio(void); diff --git a/types.h b/types.h index c21419f..af5ebfd 100644 --- a/types.h +++ b/types.h @@ -38,14 +38,6 @@ } Point; /** - * Flags for "payload ready" event. - */ -typedef struct { - bool ready; - bool crc; -} PayloadFlags; - -/** * Pointer to a function that takes an array of bytes * and returns a boolean. */