-
-
Save rikka0w0/8f40f042b1b481f7550ed80afd608f3e to your computer and use it in GitHub Desktop.
/* | |
* Example-Code that emulates a DS2502 - 1kbit EEPROM as a dell power supply | |
* | |
* Tested with | |
* - dell notebook https://forum.pjrc.com/threads/33640-Teensy-2-OneWire-Slave | |
* - DS9490R-Master, atmega328@16MHz as Slave | |
* - Arduino ProMini clone | |
* - esp8266 | |
* | |
* OneWire messaging starts when AC adapter is plugged to notebook, | |
* try to use parasite powering but unfortunately it doesn't provide enough power, | |
* so You need DC-DC converter to power MCU | |
* | |
* thanks to Nik / ploys for supplying traces of real data-traffic to figure out communication: | |
* - reset and presence detection normal | |
* - cmd from master: 0xCC -> skip rom, so there is only ONE device allowed on the bus | |
* - cmd from master: 0xF0 -> read memory | |
* - address request from master: 0x0008 | |
* - master listens for data, gets CRC of seconds cmd and address first, then listens for 3 bytes, does not listen any further | |
*/ | |
#include <Arduino.h> | |
#include "OneWireHub.h" | |
#include "DS2502.h" | |
// Valid for GPIO2 on ESP01 module | |
constexpr uint8_t pin_onewire { 2 }; | |
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 | |
// https://github.com/garyStofer/DS2502_DELL_PS/blob/master/DS2502_DELL_PS.ino | |
// constexpr const char* chargerEEPROMStr_90W = "DELL00AC090195046CN09T"; | |
// https://nickschicht.wordpress.com/2009/07/15/dell-power-supply-fault/ | |
constexpr const char* chargerEEPROMStr_90W = "DELL00AC090195046CN0C80234866161R23H8A03\x4D\x7C"; | |
constexpr const char* chargerEEPROMStr_65W = "DELL00AC065195033CN05U0927161552F31B8A03\xBC\x8F"; | |
// https://github.com/KivApple/dell-charger-emulator | |
constexpr const char* chargerEEPROMStr_45W = "DELL00AC045195023CN0CDF577243865Q27F2A05\x3D\x94"; | |
// I made this up | |
constexpr const char* chargerEEPROMStr_130W = "DELL00AC130195067CN0CDF577243865Q27F2233\x9D\x72"; | |
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 | |
// Assumes that serialStr is at least 40 bytes. | |
void crc(const char* serialStr, uint8_t* crc_l, uint8_t* crc_h) { | |
uint32_t crc = 0; | |
for (int offset = 0; offset < 40; offset++) { | |
uint8_t byte = serialStr[offset]; | |
crc ^= byte; | |
for (int i = 0; i<8; i++) { | |
if (crc & 1) | |
crc = (crc>>1) ^ 0xA001; | |
else | |
crc >>= 1; | |
} | |
} | |
*crc_l = crc & 0xFF; | |
*crc_h = (crc >> 8) & 0xFF; | |
} | |
void setup() | |
{ | |
//Serial.begin(115200); | |
//Serial.println("OneWire-Hub DS2502 aka Dell Charger"); | |
//uint8_t crc_l, crc_h; | |
//crc(chargerEEPROMStr_90W, &crc_l, &crc_h); | |
//Serial.printf("CRC(90W)= %02X %02X !!!\n", crc_l, crc_h); | |
// Setup OneWire | |
hub.attach(dellCH); | |
dellCH.writeMemory((uint8_t*)chargerEEPROMStr_130W, 42, 0); | |
//dellCH.writeMemory(charger130W, sizeof(charger130W), 0x08); | |
} | |
void loop() | |
{ | |
// following function must be called periodically | |
hub.poll(); | |
} |
On line 32, does this variable refer to a 65w charger (as the variable name suggests) or a 66w charger (as the comment suggests)?
Hi, can somebody please advice me. I see that code works for you. But i am keep getting error VERY_LONG_RESET. Maybe i am using improper board(Arduino nano clone DCCDUIONO) or I am missing some basic thing.
So far i tried based on some schematic i got by searching putting between D2 and 5V 4K7 resistor.
Also i tried both powering by USB and by 3.3V.
I can't enable debuging because it seams that it needs faster clock speed than given board provides.
I tried combinations comenting/uncomenting line 76 and 77.
Notebook never takes more than 20W which is not enought to even keep battery level :(
Maybe i am missing something really basic... or i need to use different board or different PIN as output on this board. But I dont wnat to buy differet one to find out its still same problem.
Can you please give me some advice or describe little bit better schem you are using?
Thanks
Ive no luck either, tried on Inspiron 13 5378 2in1. Using Attiny85, with no pull up, 4.7k and 10k, Connected a Logic Analyzer and got jibberish.
Laptop found on side of road, with a keyboard that smells like bong water.
PacketId, Time[s], Detail, [data]
0,7.517241791666667,Reset Pulse
5,8.004694708333334,Reset Pulse
6,8.143514583333333,Reset Pulse
30,40.530652791666668,Reset Pulse
31,42.483764708333332,Reset Pulse
31,43.259596958333333,Presence Pulse
31,43.269560291666664,Invalid Rom Command, 0xFF
31,43.269824208333333,Data, 0x27
32,43.270187083333333,Reset Pulse
32,43.276224333333332,Presence Pulse
32,43.276290333333336,Invalid Rom Command, 0x00
33,43.276785125000004,Reset Pulse
34,43.289651666666664,Reset Pulse
34,43.293610583333333,Presence Pulse
35,43.294072374999999,Reset Pulse
35,43.294765208333331,Presence Pulse
35,43.295029124999999,Invalid Rom Command, 0x00
35,43.296051916666670,Data, 0x00
36,43.296744625000002,Reset Pulse
36,43.306411166666663,Presence Pulse
37,43.307301875000000,Reset Pulse
37,43.316011541666668,Presence Pulse
38,43.316110541666667,Reset Pulse
39,43.316638374999997,Reset Pulse
Worked perfectly on an arduino nano. I just swapped the regulator to run on 3.3V instead of 5V. Thank you for sharing.
How did the sketch look when you uploaded it? I'm getting zero output.
I assume I need to comment the wattages I'm not using and uncomment the serial stuff? Software serial doen't work like that (or use printf)
Used the one from the OneWireHub examples and works great on my XPS 9550 :)
I'm writing this for prosperity : I got it to work using and arduino nano clone, what I had to do was connect the D2 pin (or the pin specified for one wire communication) to the dell ID directly WiTHOUT a pull up resistor, because anyway the dell laptop has a pull up to 3.3v on it's side...
I placed the arduino in my laptop (a 17 inch dell precision m6700 that had some free space inside as you can imagine) I connected the 5v always on power rail to the arduino ViN as it must be powered immediately when the charger is plugged in or else the charger won't be recognized.
You can look for the 5v always on in your laptop by using a multimeter and measuring capacitors, shutting down the laptop and removing the battery, then plug in the charger and power it on, the 5v always on power rail should not fluctuate at all when turning on the laptop and it should be present as soon as the charger is plugged in and the laptop is still turned off. You can also hunt down a schematic of your laptop and find the 5v always on like that.
Furthermore, I needed to emulate a 240w charger.
To emulate a charger of any wattage, you need to copy paste the 38th line, rename the variable to the wattage you need and modify the string so that is has the wattage and amps you need : as an example
constexpr const char* chargerEEPROMStr_90W = "DELL00AC090195046CN0C80234866161R23H8A03\x4D\x7C"
==> constexpr const char* chargerEEPROMStr_240W = "DELL00AC240195123CN0C80234866161R23H8A03\x4D\x7C"
See how I changed the watts from 090 to 240 as well as the amps from 04.6 to 12.3
Finally you need to modify the 76th line so that the arduino sends to the laptop the string of data that you created.
dellCH.writeMemory((uint8_t*)chargerEEPROMStr_130W, 42, 0);
==> dellCH.writeMemory((uint8_t*)chargerEEPROMStr_240W, 42, 0);
Thats it ! it should work for you hopefully !
Pin D2, thanks)