orgua / OneWireHub

OneWire slave device emulator
GNU General Public License v3.0
343 stars 86 forks source link

Working DellAC emulator example #41

Closed nik-sharky closed 6 years ago

orgua commented 6 years ago

please have a look at the already existing example: /examples/DS2502_DELLCHG

nik-sharky commented 6 years ago

please have a look at the already existing example: /examples/DS2502_DELLCHG does that work for you as well? i think it is a much cleaner solution

Hi,

I start from this example, but it doesn't work :(. Charger still Unknown, can get and send You dumps from logic analyzer for it when have time, think that problem is in duty() of DS2502. With modified Kindi's DellAC charger emulation start works well and detected as 130W original Dell.

Sorry for inappropriate Readme changes.

orgua commented 6 years ago

thanks for your feedback! i would rather do it right and use the original ds2502-code instead of a fast hack. i could imagine that the dell laptop asks for another memory-page. your hack always sends the same data. We have to find the right one and it should work. or the problem is totally unrelated. And yes, a dump can help a lot!

just to prevent other problems -> you can simplify the code of the example to:

#include "OneWireHub.h"
#include "DS2502.h"

constexpr uint8_t pin_onewire   { 8 };

constexpr uint8_t charger130W[4] = {0xFB, 0x31, 0x33, 0x30};  //130W
constexpr uint8_t charger090W[4] = {0xFB, 0x30, 0x39, 0x30};  //90W
constexpr uint8_t charger065W[4] = {0xFB, 0x30, 0x36, 0x36};  //65W

auto hub        = OneWireHub(pin_onewire);
auto dellCH    = DS2502( 0x28, 0x0D, 0x01, 0x08, 0x0B, 0x02, 0x0A);

void setup()
{
    Serial.begin(115200);
    Serial.println("OneWire-Hub DS2502 aka Dell Charger");

    // Setup OneWire
    hub.attach(dellCH);

    dellCHb.writeMemory(charger130W, sizeof(charger130W), 0x20); // write to bank 1
    dellCHb.setPageRedirection(0,1); // set memorybanks to all read from bank 1
    dellCHb.setPageRedirection(1,1);
    dellCHb.setPageRedirection(2,1);
    dellCHb.setPageRedirection(3,1);
}

void loop()
{
    // following function must be called periodically
    hub.poll();

}
orgua commented 6 years ago

oh wait, i see a problem! the ds2502 receives the cmd and the page (like in your code), but then my device sends the crc of the received three bytes! I have to check, but i think it will be 0xFB, IF we are lucky :-) this repeated 0xFB byte would confuse your laptop

orgua commented 6 years ago

funny to see how they encoded the wattage into the data. substract the 0x30 from each of the last three hex-numbers and you get each digit, except in the case of 65W, it seems so be 66W.

nik-sharky commented 6 years ago

Thanks, will try after work. After power on, notebook enable bus and as I remember it was stop conversation after first-second packet.

PulseView datagram of working conversation

orgua commented 6 years ago

i reversed the crc and it should match if your laptop is asking for byte 8 (of page 0) and following. so it should be enough if we write the data to the correct place:

   dellCH.writeMemory(charger130W, sizeof(charger130W), 0x28);

i did not look at your upload yet.

orgua commented 6 years ago

ok, i looked at your upload, seems to work out! Note: bits are in reversed order, bytewise communication looks as followed:

orgua commented 6 years ago

so, updated example:

#include "OneWireHub.h"
#include "DS2502.h"

constexpr uint8_t pin_onewire   { 8 };

constexpr uint8_t charger130W[4] = {0x31, 0x33, 0x30};  //130W (=second digit of each hex-number)
constexpr uint8_t charger090W[4] = {0x30, 0x39, 0x30};  //90W
constexpr uint8_t charger065W[4] = {0x30, 0x36, 0x36};  //66W

auto hub        = OneWireHub(pin_onewire);
auto dellCH    = DS2502( 0x28, 0x0D, 0x01, 0x08, 0x0B, 0x02, 0x0A); // address does not matter, laptop uses skipRom -> note that therefore only one slave device is allowed on the bus

void setup()
{
    Serial.begin(115200);
    Serial.println("OneWire-Hub DS2502 aka Dell Charger");

    // Setup OneWire
    hub.attach(dellCH);

    dellCH.writeMemory(charger130W, sizeof(charger130W), 0x08);
}

void loop()
{
    // following function must be called periodically
    hub.poll();
}
nik-sharky commented 6 years ago

Checked. New example works perfectly! Thank You for awesome lib!

orgua commented 6 years ago

good to hear that. thanks for your feedback and tracefile! i will leave this PR open until i update the example in the next days. OR if you want you can do this. either way: i would give you credits in the fileheader if thats ok

nik-sharky commented 6 years ago

Hi, I cleanup code, revert readme and change example to new one in my fork but can't create new pull request without closing current.

Not master of git and github yet :)

orgua commented 6 years ago

i am no master either :-( i wasn't able to check if all these commits don't mix something up, so it seemed cleaner to me to just update the example and document it some more. and i have disabled the serial and would suggest you do so to. you could also look into reducing frequency of the atmega to save power or use a irq to wake up a sleeping atmega when the master issues a reset. but i think just programming a ds2502 would be easier :-)