Skip to content

Commit

Permalink
Bring back usage of start char
Browse files Browse the repository at this point in the history
  • Loading branch information
twilco committed Jan 29, 2018
1 parent 8cb3ff9 commit 42b14f0
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 10 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ Here lies the code powering my 433mhz RF transmitter. This transmitter supports

A packet is comprised of seven different bytes:

1. `U` - This, and the following char, are our training bytes. The binary value of `U` is `01010101`, which gives any receivers' data slicers a nice square wave to sync up with. This makes them more receptive to the rest of our packet, which is important because that's where our actual data is.
2. `U` - Another literal `U` training character.
1. `U` - This is our training byte. The binary value of `U` is `01010101`, which gives any receivers' data slicers a nice square wave to sync up with. This makes them more receptive to the rest of our packet, which is important because that's where our actual data is.
2. `ª` - This is the start byte, which signals to any receiver that the bytes that follow are data bytes. The binary value of 'ª' is 10101010, which should also hopefully help train the data slicers of our receivers to be more receptive to this sender.
3. `button_byte` - Each bit in this byte corresponds to the status of our 8 non-special buttons that are on the top face of the transmitter. If a bit in this byte is `1`, it means the associated button is currently pressed.
4. `misc_byte` - A byte containing a conglomerate of bits that didn't fit anywhere else. Here we have three bits corresponding to the pressed status of our left shoulder button, right shoulder button, and the button on the analog stick. We also have the two most significant bits of both the x-axis and y-axis analog stick values. The analog values of each axis are of 10-bit resolution, so rather than allocating two whole bytes for each one we instead put these MSBs here.
5. `lsb_analog_stick_x_byte` - A byte containing the 8 least significant bits of the x-analog stick value.
6. `lsb_analog_stick_y_byte` - A byte containing the 8 least significant bits of the y-analog stick values.
7. `checksum` - Finally, we have our checksum byte. The checksum is calculated by adding up all our data bytes (so no training characters). Any overflow is ignored. This gives the receiver a simple (and admittedly not perfect) way to ensure that the data they've received is valid.
7. `checksum` - Finally, we have our checksum byte. The checksum is calculated by adding up all our data bytes (so no training characters). Any overflow is ignored. This gives the receiver a simple (and admittedly not perfect) way to ensure that the data they've received is valid.
20 changes: 13 additions & 7 deletions src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
#include <avr/interrupt.h>
#include <avr/io.h>

enum Buffer_Status construct_and_store_packet(struct Ring_Buffer* buffer, const char* training_chars, const uint8_t num_training_chars, const char* data, const uint8_t num_data_chars, bool null_terminate);
enum Buffer_Status construct_and_store_packet(struct Ring_Buffer* buffer, const char* training_chars, const uint8_t start_char, const uint8_t num_training_chars, const char* data, const uint8_t num_data_chars, bool null_terminate);

/* Since the ADC in AVRs output 10 bits, and the center of our joystick is represented by 524,
these 8 bits on their own are equivalent to 12 in decimal. To save space versus transmitting
Expand All @@ -24,18 +24,21 @@ enum Buffer_Status construct_and_store_packet(struct Ring_Buffer* buffer, const
#define DEFAULT_MISC_BYTE 0b01010000

/* Number of seconds of user inactivity before the AVR should go to sleep. */
#define SECONDS_BEFORE_SLEEP (uint16_t) 300
#define SECONDS_BEFORE_SLEEP (uint16_t) 900

/* Number of times Timer 2 needs to overflow before the AVR should go to sleep. */
#define EIGHT_BIT_TIMER_MAX 255
#define TIMER2_OVERFLOWS_BEFORE_SLEEP (uint32_t) (SECONDS_BEFORE_SLEEP / (float) ((EIGHT_BIT_TIMER_MAX * TIMER2_PRESCALER) / (float) F_CPU))

/* Use UU for our preamble, or training chars. I selected these characters because the binary value of
the 'U' char is 01010101, which supposedly gives the receivers data slicer a nice square wave to sync up with */
const char TRAINING_CHARS[] = "UU";
const char TRAINING_CHARS[] = "U";

/* Number of training chars being used - must match the length of the above variable. */
const uint8_t NUM_TRAINING_CHARS = 2;
const uint8_t NUM_TRAINING_CHARS = 1;

/* This is the char we'll use to tell the receiver that any bytes that follow are actual data bytes. */
const char START_CHAR = 0b10101010;

/* Number of data chars being sent in the packet. This should NOT include the checksum char.
Currently, we have 'misc_byte', 'button_byte', 'lsb_analog_stick_x_byte', and 'lsb_analog_stick_y_byte' */
Expand Down Expand Up @@ -151,7 +154,7 @@ int main(void)
packet_data[2] = lsb_analog_stick_x_byte;
packet_data[3] = lsb_analog_stick_y_byte;

construct_and_store_packet(&packet_buffer, TRAINING_CHARS, NUM_TRAINING_CHARS, packet_data, NUM_DATA_CHARS, false);
construct_and_store_packet(&packet_buffer, TRAINING_CHARS, START_CHAR, NUM_TRAINING_CHARS, packet_data, NUM_DATA_CHARS, false);
should_construct_packet = false;
}

Expand Down Expand Up @@ -293,20 +296,23 @@ ISR(USART_TX_vect)
@param buffer - The buffer to fill as you construct the packet.
@param training_chars - The chars used for training the receiver to sync up with this transmitter before we start sending actual data.
@param num_training_chars - The number of training chars being passed in
@param num_training_chars - The number of training chars being passed in.
@param start_char - The char used to indicate the start of the data portion of the packet
@param data - The chars representing the data portion of the packet.
@param num_data_chars - The number of data chars being passed in.
@param null_terminated - Whether or not to null terminate this packet.
@return Buffer_Status - Returns the Buffer_Status returned by the most recent write, which allows the caller to handle buffer-related issues, such as an attempted write to a full buffer.
*/
enum Buffer_Status construct_and_store_packet(struct Ring_Buffer* buffer, const char* training_chars, const uint8_t num_training_chars, const char* data, const uint8_t num_data_chars, bool null_terminate)
enum Buffer_Status construct_and_store_packet(struct Ring_Buffer* buffer, const char* training_chars, const uint8_t start_char, const uint8_t num_training_chars, const char* data, const uint8_t num_data_chars, bool null_terminate)
{
enum Buffer_Status status;

for(uint8_t i = 0; i < num_training_chars; i++) {
status = ring_buffer_write(buffer, training_chars[i]);
}

status = ring_buffer_write(buffer, start_char);

uint8_t checksum = 0;
for(uint8_t j = 0; j < num_data_chars; j++) {
status = ring_buffer_write(buffer, data[j]);
Expand Down

0 comments on commit 42b14f0

Please sign in to comment.