Closed itProfi closed 7 years ago
Nice, I like this! :)
Nice, I like this! :)
But i am beginner in С++ and I not able to write this LT8910 version, but i ready to help you :)
Chris, it's possible, that you can make in foreseeable future library with support LT8910 or no? :)
I like the idea from a cleanliness perspective, but given that Henryk's PL1167 emulator code works pretty well, and NRF24L01s seem to be more available, I'm not sure there's much practical value.
What are the biggest advantages that you see?
Probably you are right. Simply at the first stage, it was much easier for me, as a beginner, to work and explore data packets, using literally small sketches .. And in practical application, it is possible that it is not needed.
const char ssid = ".."; // cannot be longer than 32 characters! const char pass = "..."; // WiFi password
const uint8_t PIN_NRF_RST = 4; const uint8_t PIN_NRF_CS = 5; const uint8_t PIN_NRF_PKT = 10; uint8_t bufer;
LT8900 lt(PIN_NRF_CS, PIN_NRF_PKT, PIN_NRF_RST);
//Thanks to Henryk and Erantimus for providing details and checksum code. //Calculate Checksum - Returns 2 bytes.
uint8_t recieve_code() { uint8_t bbuf[20]; int packetSize = lt.read(bbuf, 20); Serial.print ("RAW packetSize ="); Serial.println(packetSize); if ((packetSize>1)&&(packetSize<20))
{ digitalWrite(LED_BUILTIN, LOW); // Turn the LED off by making the voltage HIGH delay(2); digitalWrite(LED_BUILTIN, HIGH); // Turn the LED off by making the voltage HIGH
Serial.println();
// Serial.println("Packet read OK");
uint16_t value = lt.getChannel();
Serial.print ("Current channel = ");
Serial.println (value);
Serial.print("Size of packet = ");
Serial.print(packetSize);
Serial.println();
//dump the packet.
for(int i = 0; i < packetSize; i++)
{
if (i) Serial.write(':');
if (bbuf[i] < 16) Serial.write('0');
Serial.print(bbuf[i],HEX);
Serial.println();
// Serial.write(bbuf,packetSize);
}
return bbuf[packetSize]; //crc=calc_crc(bbuf,packetSize); }
void setup_wifi() {
delay(4); // We start by connecting to a WiFi network Serial.println(); Serial.print("Connecting to "); Serial.println(ssid);
WiFi.begin(ssid, pass);
while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println(""); Serial.println("WiFi connected"); Serial.println("IP address: "); Serial.println(WiFi.localIP()); }
void setup() { // put your setup code here, to run once: pinMode(LED_BUILTIN, OUTPUT); // Initialize the LED_BUILTIN pin as an output digitalWrite(LED_BUILTIN, HIGH); Serial.begin(256000); Serial.println(F("\n\nLT8900 module sample, v0.1.\n\n"));
SPI.begin(); SPI.setFrequency(1000000);
lt.begin(); lt.setCurrentControl(12,7);
char sbuf[32];
//verify chip registers. for (int i = 0; i <= 50; i++) { uint16_t value = lt.readRegister(i);
sprintf_P(sbuf, PSTR("%d = %04x\r\n"), i, value);
Serial.print(sbuf);
} Serial.println(F("Reader mode")); lt.startListening(); lt.whatsUp(Serial); Serial.println(F("Boot completed.")); setup_wifi(); }
void loop() {
lt.setSyncWord(0x55AA00000000050A);
lt.setSyncWordLength(0x01);
lt.setChannel(0x27); //39
lt.startListening();
if (lt.available())
{
bufer=recieve_code();
lt.setSyncWord(0x1809000000007236); lt.setSyncWordLength(0x11); lt.setChannel(0x08); //39 lt.startListening(); if (lt.available()) { bufer=recieve_code();
lt.setSyncWord(0xBCCD000000009AAB);
lt.setSyncWordLength(0x11);
lt.setChannel(0x03); //3
lt.startListening();
if (lt.available())
{
bufer=recieve_code();
/// uint8_t crc=calc_crc(bbuf,packetSize);
}
lt.setSyncWord(0xBCCD000000009AAB);
lt.setSyncWordLength(0x11);
lt.setChannel(0x26); //3
lt.startListening();
if (lt.available())
{
bufer=recieve_code();
}
lt.setSyncWord(0xBCCD000000009AAB);
lt.setSyncWordLength(0x11); lt.setChannel(0x49); //3 lt.startListening(); if (lt.available()) { bufer=recieve_code(); }
lt.setSyncWord(0x03805A5A03800380);
lt.setSyncWordLength(0x10);
lt.setChannel(0x05); //5
lt.startListening();
// lt.whatsUp(Serial); if (lt.available()) { bufer=recieve_code(); lt.whatsUp(Serial);
}
}
That's all code.
Gotcha. Makes sense. Nice to not need to deal with CRC and bit fiddling. But given that it's all handled in a pretty reliable way (thanks to Henryk), I'm not sure it makes sense to switch, especially since it seems like the NRF24L01 is a more popular xceiver.
Hi there, super work decoding the protocol. I also use the different transciever, and have had quite a few problems with the nRF ones. With some minor tweaks and the addition of two files + a interface selection it should be doable without much hassle. It will only be the transport layer, all the magic happens in your layer.
Interesting. I've not noticed anything funky with the nrf24s. Do you mind sharing what kinds of issues you saw?
Yeah, I'd imagine it's possible to construct a different implementation of MiLightRadio
within MiLightClient
and it'd work pretty seamlessly.
I ordered some of these things a few days ago, but they probably won't be here for a few weeks. I can play around with it then.
Obviously happy to look at a PR before then.
Yeah, instability and quite slow. I had to implement synced fading and control between different groups, and due to all the recalcs of parameters it never looked visually good. With the other module - once set up for a type with the matching sync word, it is just a matter of sending a frame, and the channel is just a register to set also.
Aah, interesting. Yeah I'm not doing anything that requires nearly that level of precision or performance.
Definitely sounds like it's worth investigating. :)
I looked at the project, and thought about making a copy of PL1167_nRF24.cpp and make a PL1167_PL8900.cpp leaving the unnecessary functions empty making it compatible with the milightclient.... but it seems the RF24 is well incorporated.... maybe it is better to make a clone of the milightclient, accessing the new module directly, and then differ when init the client module.
I looked at the project, and thought about making a copy of PL1167_nRF24.cpp and make a PL1167_PL8900.cpp leaving the unnecessary functions empty making it compatible with the milightclient.... but it seems the RF24 is well incorporated.... maybe it is better to make a clone of the milightclient, accessing the new module directly, and then differ when init the client module.
If need, i can be a tester with LT8900 or LT8920..:)
I feel like MiLightRadio
is the right layer of abstraction here. I guess it seems like exactly the interface for the "transport layer" you referred to above. Without knowing exactly what you'll need to do, the methods in this class seem more or less exactly what you what to swap implementations for:
int begin();
bool available();
int read(uint8_t frame[], size_t &frame_length);
int dupesReceived();
int write(uint8_t frame[], size_t frame_length);
int resend();
int configure();
Obviously some things like the reference to an AbstractPL1167
would need to be pulled into a separate implementation (something like NrfMiLightRadio
, maybe?)
Then it'd just be a matter of passing or constructing a different type of MiLightRadio
in MiLightClient
.
I think the AbstractPL1167 can be omitted, and then there must be added to RadioStack also.
RadioStack is just meant to be pairs of MiLightRadio and MiLightRadioConfig. I think stuff specific to the NRF would be pulled into the NRF-specific implementation of MiLightRadio.
The interfaces are messy and bleed into each other because the transport layer wasn't an important abstraction. Obviously we'd want to clean that up before adding a new impl. :)
Let me know if I can help out making the code more amenable to this.
I will try to make a mockup, and then you can come with some inputs afterwards.
Just an update - I can receive something, but will just tidy up the code... hopefully something within a day or two
Awesome :)
There might be added a further pin setup for a hardware reset pin - if set to '0' then it is not used. Furthermore a setup of RF module used: nRF or LT8900 compatible...
I have reception running, and also transmission, one thing though is I have three RGB_CCT bulbs on the same group, and when sending an on/off - one or two does not respond, but then one is reacting as it should. And then the behaviour shuffles between the bulbs.... it is late here - will look into it the next few days.
Might be some timing issues caused by the stream and my resend function... can be sortes.
Awesome! I'm excited to test this out. I noticed yesterday while testing some of the UDP changes that something seems pretty sluggish, and I'm wondering if it's the NRF. Could totally be my rather unoptimized UDP handling too, but one can hope :)
Have you tried multiple RGB_CCT bulbs in a group with the nRF interface.... do they all respond as they should - I keep getting the same issue, where they shuffle in the behaviour? What about the frame that is being sent when powering the remotes, could that be a "MASTER" frame the resets the bulbs sequence number, to make them listen again for a low sequence number? Do they respond, if the number decrement instead of increment?
Yeah, I have three different groups of RGB+CCT bulbs I've been using. Two of them have three bulbs, the other has two. They all at least appear to act in unison. It's definitely necessary to send repeat packets. I'm sending 30-50 on each channel the bulbs listen on. This might be excessive, but I've found that it's a good balance of responsiveness and reliability.
Bulbs do seem to ignore packets that have the same sequence value as the last packet they saw. I noticed this when replaying packets. I haven't tried sending packets with decreasing sequence numbers. My remotes and wifi box definitely seem to send packets with increasing sequence values.
As far as I've been able to tell, official devices are only sending the same packet multiple times per action, and not multiple packets.
For best result on the other bulbs I've used around 100 transmissions spread across all channels. I've just switched to the v1.1.0 branch - but now PlatformIO is acting up.... doh. It might be the sequence number just needs to be different from command to command, to prevent acting many times on the re-transmits.
Gotcha, interesting. I suppose it depends a bit on timing and signal strength?
What's PlatformIO doing? Hope I didn't break something. :(
Right, makes sense that it'd only need to be different. Only meant to suggest that the official devices seem to increment the sequence number by one rather than changing it by some other function.
PlatformIO is running again with latest v1.1.0 - but still the same. I can pair all three bulbs with the gateway, but they actually flashed green out of sync, and if I sync with a real remote, they pair and flash green in sync.... so something is off when transmitting the frames. Reception works super, but just the problem with transmission. What can it be......they change pattern on pressing the on toggle switch on the web interface. But the encrypted frame must be OK, as some of the bulbs react. Can it be related to the switch between channels..... or.... well. Night time here... .I'm off to bed.
Problem solved:) - stupid mistake with an internal value being used instead of the right one - will clean up the code, and try to make a way to switch between the two interfaces.
An option to select different modules must be added, but what about showing the connection state to the module on the web app. Makes it easy to identify if everything is connected OK.
Where try new code? :)
Will see if I can get it done later tonight..
Awesome! Was it was performant as you hoped?
Settings
is where we'd put a setting to swap between radio modules, btw.
Yep - working on it.... due to heavy work activity it might take a day or two - sorry. Will try to make it as fast as possible, or at least upload something nearly finished.
How will you prefer to get the changes...?
Pull request sounds good to me if that works for you.
Should probably start a new minor release branch for it (v1.2.0).
OK - I will make a branch v1.2.0 in my fork, commit the changes, and see if I can get the pull to work. Might get the time later today.
OK - I will make a branch v1.2.0 in my fork, commit the changes, and see if I can get the pull to work. Might get the time later today.
Can you say pinout by default for LT8900 (in your version)?
I use cs 15 and pin 4, reset is not used
But you can set it from the web app
Like this:
Reset not used (on LT8900) Whats about PKT?
Pkt shares the setting with csne, and you can connect reset also just assign a value different than 0 in the web app.
Pkt is used as rx frame ready detection
From my fork you just cannot save the module type yet. I saw somewhere that sidoh mentioned a rewrite, so thought is was more fun if you could test it.
I propose correct this lablel to PL1167/LT8900/8910/8920
Pkt shares the setting with csne
You mean csn_pin?
Makes sense with the label☺ Yes sorry, the csn pin.
From my fork you just cannot save the module type yet. I saw somewhere that sidoh mentioned a rewrite, so thought is was more fun if you could test it.
Rewrite of the web app? Yeah, made #23 for that. Not sure when I'll get around to that, though.
Chris! Is it possible make version of library with support original LT8910 module support? It's fully describe in https://bitbucket.org/robvanderveer/lt8900lib IMHO is easer and simple, that use VIRTUAL NRF24... I use it to decode all packets. It's cost in Cina on Taobao - ¥ 3.35 ( 约USD 0.49) This guys also use this module https://authometion.com/shop/it/ Their forum -http://www.authometion.com/forum/viewforum.php?f=2 Their repo - https://github.com/pmoscetta/authometion-milight