Skip to content

Commit

Permalink
Major refactor of radio/remote config. Add support for FUT089 remote
Browse files Browse the repository at this point in the history
  • Loading branch information
Chris Mullins committed Sep 23, 2017
1 parent c3fde5e commit 02ce659
Show file tree
Hide file tree
Showing 37 changed files with 528 additions and 352 deletions.
7 changes: 6 additions & 1 deletion lib/Helpers/Size.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
#include <Arduino.h>

#ifndef _SIZE_H
#define _SIZE_H

template<typename T, size_t sz>
size_t size(T(&)[sz]) {
return sz;
}
}

#endif
11 changes: 6 additions & 5 deletions lib/MQTT/MqttClient.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include <IntParsing.h>
#include <ArduinoJson.h>
#include <WiFiClient.h>
#include <MiLightRadioConfig.h>

MqttClient::MqttClient(Settings& settings, MiLightClient*& milightClient)
: milightClient(milightClient),
Expand Down Expand Up @@ -85,7 +86,7 @@ void MqttClient::handleClient() {
mqttClient->loop();
}

void MqttClient::sendUpdate(MiLightRadioType type, uint16_t deviceId, uint16_t groupId, const char* update) {
void MqttClient::sendUpdate(const MiLightRemoteConfig& remoteConfig, uint16_t deviceId, uint16_t groupId, const char* update) {
String topic = settings.mqttUpdateTopicPattern;

if (topic.length() == 0) {
Expand All @@ -97,7 +98,7 @@ void MqttClient::sendUpdate(MiLightRadioType type, uint16_t deviceId, uint16_t g

topic.replace(":device_id", String("0x") + deviceIdStr);
topic.replace(":group_id", String(groupId));
topic.replace(":device_type", MiLightRadioConfig::fromType(type)->name);
topic.replace(":device_type", remoteConfig.name);

#ifdef MQTT_DEBUG
printf_P(PSTR("MqttClient - publishing update to %s: %s\n"), topic.c_str(), update);
Expand All @@ -123,7 +124,7 @@ void MqttClient::subscribe() {
void MqttClient::publishCallback(char* topic, byte* payload, int length) {
uint16_t deviceId = 0;
uint8_t groupId = 0;
MiLightRadioConfig* config = &MilightRgbCctConfig;
const MiLightRemoteConfig* config = &FUT092Config;
char cstrPayload[length + 1];
cstrPayload[length] = 0;
memcpy(cstrPayload, payload, sizeof(byte)*length);
Expand All @@ -148,7 +149,7 @@ void MqttClient::publishCallback(char* topic, byte* payload, int length) {
}

if (tokenBindings.hasBinding("device_type")) {
config = MiLightRadioConfig::fromString(tokenBindings.get("device_type"));
config = MiLightRemoteConfig::fromType(tokenBindings.get("device_type"));
}

StaticJsonBuffer<400> buffer;
Expand All @@ -158,6 +159,6 @@ void MqttClient::publishCallback(char* topic, byte* payload, int length) {
printf_P(PSTR("MqttClient - device %04X, group %u\n"), deviceId, groupId);
#endif

milightClient->prepare(*config, deviceId, groupId);
milightClient->prepare(config, deviceId, groupId);
milightClient->update(obj);
}
3 changes: 2 additions & 1 deletion lib/MQTT/MqttClient.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include <Settings.h>
#include <PubSubClient.h>
#include <WiFiClient.h>
#include <MiLightRadioConfig.h>

#ifndef MQTT_CONNECTION_ATTEMPT_FREQUENCY
#define MQTT_CONNECTION_ATTEMPT_FREQUENCY 5000
Expand All @@ -18,7 +19,7 @@ class MqttClient {
void begin();
void handleClient();
void reconnect();
void sendUpdate(MiLightRadioType type, uint16_t deviceId, uint16_t groupId, const char* update);
void sendUpdate(const MiLightRemoteConfig& remoteConfig, uint16_t deviceId, uint16_t groupId, const char* update);

private:
WiFiClient tcpClient;
Expand Down
2 changes: 1 addition & 1 deletion lib/MiLight/CctPacketFormatter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
void CctPacketFormatter::initializePacket(uint8_t* packet) {
size_t packetPtr = 0;

packet[packetPtr++] = CCT;
packet[packetPtr++] = 0x5A;
packet[packetPtr++] = deviceId >> 8;
packet[packetPtr++] = deviceId & 0xFF;
packet[packetPtr++] = groupId;
Expand Down
59 changes: 59 additions & 0 deletions lib/MiLight/FUT089PacketFormatter.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
#include <FUT089PacketFormatter.h>
#include <V2RFEncoding.h>
#include <Units.h>

void FUT089PacketFormatter::modeSpeedDown() {
command(FUT089_ON, FUT089_MODE_SPEED_DOWN);
}

void FUT089PacketFormatter::modeSpeedUp() {
command(FUT089_ON, FUT089_MODE_SPEED_UP);
}

void FUT089PacketFormatter::updateMode(uint8_t mode) {
command(FUT089_MODE, mode);
}

void FUT089PacketFormatter::updateBrightness(uint8_t brightness) {
command(FUT089_BRIGHTNESS, brightness);
}

void FUT089PacketFormatter::updateHue(uint16_t value) {
uint8_t remapped = Units::rescale(value, 255, 360);
updateColorRaw(remapped);
}

void FUT089PacketFormatter::updateColorRaw(uint8_t value) {
command(FUT089_COLOR, FUT089_COLOR_OFFSET + value);
}

void FUT089PacketFormatter::updateTemperature(uint8_t value) {
command(FUT089_KELVIN, value);
}

void FUT089PacketFormatter::updateSaturation(uint8_t value) {
command(FUT089_SATURATION, value);
}

void FUT089PacketFormatter::updateColorWhite() {
command(FUT089_ON, FUT089_WHITE_MODE);
}

void FUT089PacketFormatter::enableNightMode() {
uint8_t arg = groupCommandArg(OFF, groupId);
command(FUT089_ON | 0x80, arg);
}

void FUT089PacketFormatter::parsePacket(const uint8_t *packet, JsonObject& result) {
uint8_t packetCopy[V2_PACKET_LEN];
memcpy(packetCopy, packet, V2_PACKET_LEN);
V2RFEncoding::decodeV2Packet(packetCopy);

result["device_id"] = (packetCopy[2] << 8) | packetCopy[3];
result["group_id"] = packetCopy[7];
result["device_type"] = "rgb_cct";

if (! result.containsKey("state")) {
result["state"] = "ON";
}
}
45 changes: 45 additions & 0 deletions lib/MiLight/FUT089PacketFormatter.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#include <V2PacketFormatter.h>

#ifndef _FUT089_PACKET_FORMATTER_H
#define _FUT089_PACKET_FORMATTER_H

#define FUT089_COLOR_OFFSET 0

enum MiLightFUT089Command {
FUT089_ON = 0x01,
FUT089_OFF = 0x01,
FUT089_COLOR = 0x02,
FUT089_BRIGHTNESS = 0x05,
FUT089_MODE = 0x06,
FUT089_KELVIN = 0x07,
FUT089_SATURATION = 0x07
};

enum MiLightFUT089Arguments {
FUT089_MODE_SPEED_UP = 0x12,
FUT089_MODE_SPEED_DOWN = 0x13,
FUT089_WHITE_MODE = 0x14
};

class FUT089PacketFormatter : public V2PacketFormatter {
public:
FUT089PacketFormatter()
: V2PacketFormatter(0x25, 8)
{ }

virtual void updateBrightness(uint8_t value);
virtual void updateHue(uint16_t value);
virtual void updateColorRaw(uint8_t value);
virtual void updateColorWhite();
virtual void updateTemperature(uint8_t value);
virtual void updateSaturation(uint8_t value);
virtual void enableNightMode();

virtual void modeSpeedDown();
virtual void modeSpeedUp();
virtual void updateMode(uint8_t mode);

virtual void parsePacket(const uint8_t* packet, JsonObject& result);
};

#endif
152 changes: 46 additions & 106 deletions lib/MiLight/LT8900MiLightRadio.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ LT8900MiLightRadio::LT8900MiLightRadio(byte byCSPin, byte byResetPin, byte byPkt
SPI.setBitOrder(MSBFIRST);

//Initialize transceiver with correct settings
vInitRadioModule(config.type);
vInitRadioModule();
delay(50);

// Check if HW is connected
Expand Down Expand Up @@ -90,108 +90,48 @@ bool LT8900MiLightRadio::bCheckRadioConnection(void)
/**************************************************************************/
// Initialize radio module
/**************************************************************************/
void LT8900MiLightRadio::vInitRadioModule(MiLightRadioType type) {
if (type == RGB_CCT) {
bool bWriteDefaultDefault = true; // Is it okay to use the default power up values, without setting them

regWrite16(0x00, 0x6F, 0xE0, 7); // Recommended value by PMmicro
regWrite16(0x02, 0x66, 0x17, 7); // Recommended value by PMmicro
regWrite16(0x04, 0x9C, 0xC9, 7); // Recommended value by PMmicro

regWrite16(0x05, 0x66, 0x37, 7); // Recommended value by PMmicro
regWrite16(0x07, 0x00, 0x4C, 7); // PL1167's TX/RX Enable and Channel Register, Default channel 76
regWrite16(0x08, 0x6C, 0x90, 7); // Recommended value by PMmicro
regWrite16(0x09, 0x48, 0x00, 7); // PA Control register

regWrite16(0x0B, 0x00, 0x08, 7); // Recommended value by PMmicro
regWrite16(0x0D, 0x48, 0xBD, 7); // Recommended value by PMmicro
regWrite16(0x16, 0x00, 0xFF, 7); // Recommended value by PMmicro
regWrite16(0x18, 0x00, 0x67, 7); // Recommended value by PMmicro

regWrite16(0x1A, 0x19, 0xE0, 7); // Recommended value by PMmicro
regWrite16(0x1B, 0x13, 0x00, 7); // Recommended value by PMmicro

regWrite16(0x20, 0x48, 0x00, 7); // Recommended value by PMmicro
regWrite16(0x21, 0x3F, 0xC7, 7); // Recommended value by PMmicro
regWrite16(0x22, 0x20, 0x00, 7); // Recommended value by PMmicro
regWrite16(0x23, 0x03, 0x00, 7); // Recommended value by PMmicro

regWrite16(0x24, 0x72, 0x36, 7); // Sync R0
regWrite16(0x27, 0x18, 0x09, 7); // Sync R3
regWrite16(0x28, 0x44, 0x02, 7); // Recommended value by PMmicro
regWrite16(0x29, 0xB0, 0x00, 7); // Recommended value by PMmicro
regWrite16(0x2A, 0xFD, 0xB0, 7); // Recommended value by PMmicro

if (bWriteDefaultDefault == true) {
regWrite16(0x01, 0x56, 0x81, 7); // Recommended value by PMmicro
regWrite16(0x0A, 0x7F, 0xFD, 7); // Recommended value by PMmicro
regWrite16(0x0C, 0x00, 0x00, 7); // Recommended value by PMmicro
regWrite16(0x17, 0x80, 0x05, 7); // Recommended value by PMmicro
regWrite16(0x19, 0x16, 0x59, 7); // Recommended value by PMmicro
regWrite16(0x1C, 0x18, 0x00, 7); // Recommended value by PMmicro

regWrite16(0x25, 0x00, 0x00, 7); // Recommended value by PMmicro
regWrite16(0x26, 0x00, 0x00, 7); // Recommended value by PMmicro
regWrite16(0x2B, 0x00, 0x0F, 7); // Recommended value by PMmicro
}
} else if( (type == RGBW) || (type == CCT) || (type == RGB) ) {
regWrite16(0x00, 0x6F, 0xE0, 7); // Recommended value by PMmicro
regWrite16(0x01, 0x56, 0x81, 7); // Recommended value by PMmicro
regWrite16(0x02, 0x66, 0x17, 7); // Recommended value by PMmicro
regWrite16(0x04, 0x9C, 0xC9, 7); // Recommended value by PMmicro
regWrite16(0x05, 0x66, 0x37, 7); // Recommended value by PMmicro
regWrite16(0x07, 0x00, 0x4C, 7); // PL1167's TX/RX Enable and Channel Register
regWrite16(0x08, 0x6C, 0x90, 7); // Recommended value by PMmicro
regWrite16(0x09, 0x48, 0x00, 7); // PL1167's PA Control Register
regWrite16(0x0A, 0x7F, 0xFD, 7); // Recommended value by PMmicro
regWrite16(0x0B, 0x00, 0x08, 7); // PL1167's RSSI OFF Control Register -- ???
regWrite16(0x0C, 0x00, 0x00, 7); // Recommended value by PMmicro
regWrite16(0x0D, 0x48, 0xBD, 7); // Recommended value by PMmicro
regWrite16(0x16, 0x00, 0xFF, 7); // Recommended value by PMmicro
regWrite16(0x17, 0x80, 0x05, 7); // PL1167's VCO Calibration Enable Register
regWrite16(0x18, 0x00, 0x67, 7); // Recommended value by PMmicro
regWrite16(0x19, 0x16, 0x59, 7); // Recommended value by PMmicro
regWrite16(0x1A, 0x19, 0xE0, 7); // Recommended value by PMmicro
regWrite16(0x1B, 0x13, 0x00, 7); // Recommended value by PMmicro
regWrite16(0x1C, 0x18, 0x00, 7); // Recommended value by PMmicro
regWrite16(0x20, 0x48, 0x00, 7); // PL1167's Data Configure Register: LEN_PREAMBLE = 010 -> (0xAAAAAA) 3 bytes, LEN_SYNCWORD = 01 -> 32 bits, LEN_TRAILER = 000 -> (0x05) 4 bits, TYPE_PKT_DAT = 00 -> NRZ law data, TYPE_FEC = 00 -> No FEC
regWrite16(0x21, 0x3F, 0xC7, 7); // PL1167's Delay Time Control Register 0
regWrite16(0x22, 0x20, 0x00, 7); // PL1167's Delay Time Control Register 1
regWrite16(0x23, 0x03, 0x00, 7); // PL1167's Power Management and Miscellaneous Register

regWrite16(0x28, 0x44, 0x02, 7); // PL1167's FIFO and SYNCWORD Threshold Register
regWrite16(0x29, 0xB0, 0x00, 7); // PL1167's Miscellaneous Register: CRC_ON = 1 -> ON, SCR_ON = 0 -> OFF, EN_PACK_LEN = 1 -> ON, FW_TERM_TX = 1 -> ON, AUTO_ACK = 0 -> OFF, PKT_LEVEL = 0 -> PKT active high, CRC_INIT_DAT = 0
regWrite16(0x2A, 0xFD, 0xB0, 7); // PL1167's SCAN RSSI Register 0
regWrite16(0x2B, 0x00, 0x0F, 7); // PL1167's SCAN RSSI Register 1
delay(200);
regWrite16(0x80, 0x00, 0x00, 7);
regWrite16(0x81, 0xFF, 0xFF, 7);
regWrite16(0x82, 0x00, 0x00, 7);
regWrite16(0x84, 0x00, 0x00, 7);
regWrite16(0x85, 0xFF, 0xFF, 7);
regWrite16(0x87, 0xFF, 0xFF, 7);
regWrite16(0x88, 0x00, 0x00, 7);
regWrite16(0x89, 0xFF, 0xFF, 7);
regWrite16(0x8A, 0x00, 0x00, 7);
regWrite16(0x8B, 0xFF, 0xFF, 7);
regWrite16(0x8C, 0x00, 0x00, 7);
regWrite16(0x8D, 0xFF, 0xFF, 7);
regWrite16(0x96, 0x00, 0x00, 7);
regWrite16(0x97, 0xFF, 0xFF, 7);
regWrite16(0x98, 0x00, 0x00, 7);
regWrite16(0x99, 0xFF, 0xFF, 7);
regWrite16(0x9A, 0x00, 0x00, 7);
regWrite16(0x9B, 0xFF, 0xFF, 7);
regWrite16(0x9C, 0x00, 0x00, 7);
regWrite16(0xA0, 0x00, 0x00, 7);
regWrite16(0xA1, 0xFF, 0xFF, 7);
regWrite16(0xA2, 0x00, 0x00, 7);
regWrite16(0xA3, 0xFF, 0xFF, 7);
regWrite16(0xA8, 0x00, 0x00, 7);
regWrite16(0xA9, 0xFF, 0xFF, 7);
regWrite16(0xAA, 0x00, 0x00, 7);
regWrite16(0xAB, 0xFF, 0xFF, 7);
regWrite16(0x07, 0x00, 0x00, 7); // Disable TX/RX and set radio channel to 0
void LT8900MiLightRadio::vInitRadioModule() {
bool bWriteDefaultDefault = true; // Is it okay to use the default power up values, without setting them

regWrite16(0x00, 0x6F, 0xE0, 7); // Recommended value by PMmicro
regWrite16(0x02, 0x66, 0x17, 7); // Recommended value by PMmicro
regWrite16(0x04, 0x9C, 0xC9, 7); // Recommended value by PMmicro

regWrite16(0x05, 0x66, 0x37, 7); // Recommended value by PMmicro
regWrite16(0x07, 0x00, 0x4C, 7); // PL1167's TX/RX Enable and Channel Register, Default channel 76
regWrite16(0x08, 0x6C, 0x90, 7); // Recommended value by PMmicro
regWrite16(0x09, 0x48, 0x00, 7); // PA Control register

regWrite16(0x0B, 0x00, 0x08, 7); // Recommended value by PMmicro
regWrite16(0x0D, 0x48, 0xBD, 7); // Recommended value by PMmicro
regWrite16(0x16, 0x00, 0xFF, 7); // Recommended value by PMmicro
regWrite16(0x18, 0x00, 0x67, 7); // Recommended value by PMmicro

regWrite16(0x1A, 0x19, 0xE0, 7); // Recommended value by PMmicro
regWrite16(0x1B, 0x13, 0x00, 7); // Recommended value by PMmicro

regWrite16(0x20, 0x48, 0x00, 7); // Recommended value by PMmicro
regWrite16(0x21, 0x3F, 0xC7, 7); // Recommended value by PMmicro
regWrite16(0x22, 0x20, 0x00, 7); // Recommended value by PMmicro
regWrite16(0x23, 0x03, 0x00, 7); // Recommended value by PMmicro

regWrite16(0x24, 0x72, 0x36, 7); // Sync R0
regWrite16(0x27, 0x18, 0x09, 7); // Sync R3
regWrite16(0x28, 0x44, 0x02, 7); // Recommended value by PMmicro
regWrite16(0x29, 0xB0, 0x00, 7); // Recommended value by PMmicro
regWrite16(0x2A, 0xFD, 0xB0, 7); // Recommended value by PMmicro

if (bWriteDefaultDefault == true) {
regWrite16(0x01, 0x56, 0x81, 7); // Recommended value by PMmicro
regWrite16(0x0A, 0x7F, 0xFD, 7); // Recommended value by PMmicro
regWrite16(0x0C, 0x00, 0x00, 7); // Recommended value by PMmicro
regWrite16(0x17, 0x80, 0x05, 7); // Recommended value by PMmicro
regWrite16(0x19, 0x16, 0x59, 7); // Recommended value by PMmicro
regWrite16(0x1C, 0x18, 0x00, 7); // Recommended value by PMmicro

regWrite16(0x25, 0x00, 0x00, 7); // Recommended value by PMmicro
regWrite16(0x26, 0x00, 0x00, 7); // Recommended value by PMmicro
regWrite16(0x2B, 0x00, 0x0F, 7); // Recommended value by PMmicro
}
}

Expand Down Expand Up @@ -380,7 +320,7 @@ int LT8900MiLightRadio::begin()
/**************************************************************************/
int LT8900MiLightRadio::configure()
{
vInitRadioModule(_config.type);
vInitRadioModule();
vSetSyncWord(_config.syncword3, 0,0,_config.syncword0);
vStartListening(_config.channels[0]);
return 0;
Expand Down Expand Up @@ -412,8 +352,8 @@ int LT8900MiLightRadio::read(uint8_t frame[], size_t &frame_length)
Serial.println(F("LT8900: Radio was available, reading packet..."));
#endif

uint8_t buf[_config.getPacketLength()];
int packetSize = iReadRXBuffer(buf, _config.getPacketLength());
uint8_t buf[MILIGHT_MAX_PACKET_LENGTH];
int packetSize = iReadRXBuffer(buf, MILIGHT_MAX_PACKET_LENGTH);

if (packetSize > 0) {
frame_length = packetSize;
Expand Down
2 changes: 1 addition & 1 deletion lib/MiLight/LT8900MiLightRadio.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ class LT8900MiLightRadio : public MiLightRadio {

private:

void vInitRadioModule(MiLightRadioType type);
void vInitRadioModule();
void vSetSyncWord(uint16_t syncWord3, uint16_t syncWord2, uint16_t syncWord1, uint16_t syncWord0);
uint16_t uiReadRegister(uint8_t reg);
void regWrite16(byte ADDR, byte V1, byte V2, byte WAIT);
Expand Down
Loading

0 comments on commit 02ce659

Please sign in to comment.