Skip to content

Commit

Permalink
First draft
Browse files Browse the repository at this point in the history
  • Loading branch information
gdsports committed Aug 3, 2018
1 parent e042588 commit cd56cec
Show file tree
Hide file tree
Showing 4 changed files with 442 additions and 3 deletions.
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2018 gdsports
Copyright (c) 2018 [email protected]

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
82 changes: 80 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,80 @@
# rfm69-usb-devices
RFM69 USB extender
# Wireless USB Keyboard Extender Using RFM69
A long range wireless USB keyboard in two parts.

The USB keyboard plugs into the sender. The sender must have USB host
capabiiity to communicate with the keyboard. The SAMD21 M0 is used for this
project. Every key press and release generates a USB HID (Human Interface
Descriptor) report. The report is a 8 byte data struture which is sent using
the RFM69 radio to the receiver.

The receiver plugs into the computer via a USB port. No other components are
required because the RFM69HCW radio is integrated with the Feather board. The
receiver takes USB HID reports from the RFM69 radio then sends to the computer
over USB.

## USB keyboard receiver

915 MHz -> Feather 32u4 RFM69HCW -> USB cable -> Computer

The receiver may use the M0 or 32u4 Feather version. The 32u4 was used here for
no other reason than it was available.

* Adafruit Feather 32u4 RFM69HCW Packet Radio

Headers do not need to be installed on the board. An antenna is required.

Upload the RFM69KbdRFM69Rx.ino sketch. This program reads USB HID reports from
the RFM69 radio then sends them out the USB keyboard device interface to the
computer. The Feather is powered from the computer.

## USB keyboard sender

USB USB OTG Host
Keyboard -> cable/adapter -> Feather M0 RFM69HCW -> 915 MHz
GND USB Tx
| ^ |
| | |
| | v
GND 5V RxD
CP2104 USB to serial -> Computer

WARNING: The sender must use the M0 Feather version because the M0 has USB host
capability. The 32u4 does not.

* USB keyboard
* USB OTG Host Cable - MicroB OTG male to A female
* Adafruit Feather M0 RFM69HCW Packet Radio
* Adafruit CP2104 Friend - USB to Serial Converter

Headers and breadboard are used to connect to power to the Feather board. An
antenna is required.

Upload the RFM69KbdRFM69Tx.ino sketch. This program reads USB HID reports from
the USB keyboard then sends the USB HID reports to the RFM69 radio.

### Upload mode

Powering the Feather is trickier compared to the receiver. When uploading, the
Feather is powered from the computer. The other 5V power source (see below)
MUST be disconnected.

WARNING: Do not connect more than one power source to the Feather at the same
time.

WARNING: When using USB host mode, the Feather RESET button must be pressed
twice to put the board in upload mode. Automatic upload does not work.

Feather M0 RFM69HCW -> USB cable -> Computer

### Sender mode

When using the Feather in keyboard sender mode, the Feather must be powered by
a 5V power source connected to its USB pin. In this case, a CP2104 USB serial
board provides the 5V power as well as USB serial for debug output via the
Serial1 UART Tx pin.

When debugging is completed, the CP2104 board is not needed but a 5V power
supply is still required.

The Feather battery power option is not useful here because Lithium batteries
do not provide 5V.
165 changes: 165 additions & 0 deletions USBKbdRFM69Rx/USBKbdRFM69Rx.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
/*
* Keyboard Wireless Extender Example -- Receiver
* Receive USB keyboard HID report from RFM69 raw mode then send on USB keyboard
* device interface. Tested on Adafruit Feather 32u4 with RFM69HCW.
* Based on an example included in Adafruit's fork of the RadioHead library.
*/

//8#define DEBUG_KEYBOARD_RAW

#include <Keyboard.h>

#include <SPI.h>
#include <RH_RF69.h>
#include <RHReliableDatagram.h>

/************ Radio Setup ***************/

// Change to 434.0 or other frequency, must match RX's freq!
#define RF69_FREQ 915.0

// who am i? (server address)
#define MY_ADDRESS 1


#if defined (__AVR_ATmega32U4__) // Feather 32u4 w/Radio
#define RFM69_CS 8
#define RFM69_INT 7
#define RFM69_RST 4
#define LED 13
#endif

#if defined(ARDUINO_SAMD_FEATHER_M0) // Adafruit Feather M0 w/Radio
#define RFM69_CS 8
#define RFM69_INT 3
#define RFM69_RST 4
#define LED LED_BUILTIN
#elif defined(ARDUINO_ITSYBITSY_M0) // Adafruit ItsyBitsy M0
#define RFM69_CS 10
#define RFM69_INT 7
#define RFM69_RST 9
#define LED LED_BUILTIN
#elif defined(ARDUINO_SAMD_ZERO) // Arduino Zero
#define RFM69_CS 4
#define RFM69_INT 3
#define RFM69_RST 2
#define LED LED_BUILTIN
#endif

#if defined (__AVR_ATmega328P__) // Feather 328P w/wing
#define RFM69_INT 3 //
#define RFM69_CS 4 //
#define RFM69_RST 2 // "A"
#define LED 13
#endif

#if defined(ESP8266) // ESP8266 feather w/wing
#define RFM69_CS 2 // "E"
#define RFM69_IRQ 15 // "B"
#define RFM69_RST 16 // "D"
#define LED 0
#endif

#if defined(ESP32) // ESP32 feather w/wing
#define RFM69_RST 13 // same as LED
#define RFM69_CS 33 // "B"
#define RFM69_INT 27 // "A"
#define LED 13
#endif

/* Teensy 3.x w/wing
#define RFM69_RST 9 // "A"
#define RFM69_CS 10 // "B"
#define RFM69_IRQ 4 // "C"
#define RFM69_IRQN digitalPinToInterrupt(RFM69_IRQ )
*/

/* WICED Feather w/wing
#define RFM69_RST PA4 // "A"
#define RFM69_CS PB4 // "B"
#define RFM69_IRQ PA15 // "C"
#define RFM69_IRQN RFM69_IRQ
*/

// Singleton instance of the radio driver
RH_RF69 rf69(RFM69_CS, RFM69_INT);

// Class to manage message delivery and receipt, using the driver declared above
RHReliableDatagram rf69_manager(rf69, MY_ADDRESS);

void setup()
{
SERIAL_PORT_MONITOR.begin(115200);
//while (!Serial) { delay(1); } // wait until serial console is open, remove if not tethered to computer

pinMode(LED, OUTPUT);
pinMode(RFM69_RST, OUTPUT);
digitalWrite(RFM69_RST, LOW);

SERIAL_PORT_MONITOR.println("Feather RFM69 RX Test!");
SERIAL_PORT_MONITOR.println();

// manual reset
digitalWrite(RFM69_RST, HIGH);
delay(10);
digitalWrite(RFM69_RST, LOW);
delay(10);

if (!rf69_manager.init()) {
SERIAL_PORT_MONITOR.println("RFM69 radio init failed");
while (1);
}
SERIAL_PORT_MONITOR.println("RFM69 radio init OK!");

// Defaults after init are 434.0MHz, modulation GFSK_Rb250Fd250, +13dbM (for low power module)
// No encryption
if (!rf69.setFrequency(RF69_FREQ)) {
SERIAL_PORT_MONITOR.println("setFrequency failed");
}

// If you are using a high power RF69 eg RFM69HW, you *must* set a Tx power with the
// ishighpowermodule flag set like this:
rf69.setTxPower(20, true); // range from 14-20 for power, 2nd arg must be true for 69HCW

// The encryption key has to be the same as the one in the server
uint8_t key[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08
};
rf69.setEncryptionKey(key);

pinMode(LED, OUTPUT);

SERIAL_PORT_MONITOR.print("RFM69 radio @");
SERIAL_PORT_MONITOR.print((int)RF69_FREQ);
SERIAL_PORT_MONITOR.println(" MHz");

Keyboard.begin();
}

uint8_t buf[RH_RF69_MAX_MESSAGE_LEN];

void loop() {
if (rf69_manager.available()) {
// Should be a message for us now
uint8_t len = sizeof(buf);
uint8_t from;
if (rf69_manager.recvfromAck(buf, &len, &from)) {
if (!len) return;
HID().SendReport(2, buf, len);
#ifdef DEBUG_KEYBOARD_RAW
SERIAL_PORT_MONITOR.print("Received [");
SERIAL_PORT_MONITOR.print(len);
SERIAL_PORT_MONITOR.print("]: ");
for (uint8_t i = 0; i < len ; i++) {
SERIAL_PORT_MONITOR.print(' '); SERIAL_PORT_MONITOR.print(buf[i], HEX);
}
SERIAL_PORT_MONITOR.println();
SERIAL_PORT_MONITOR.print("RSSI: ");
SERIAL_PORT_MONITOR.println(rf69.lastRssi(), DEC);
#endif
} else {
SERIAL_PORT_MONITOR.println("Receive failed");
}
}
}

Loading

0 comments on commit cd56cec

Please sign in to comment.