Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HELP - ESP32 and PiJuice Zero #1079

Open
SerinoA9 opened this issue Apr 19, 2024 · 5 comments
Open

HELP - ESP32 and PiJuice Zero #1079

SerinoA9 opened this issue Apr 19, 2024 · 5 comments

Comments

@SerinoA9
Copy link

Hello,

I have a question I would like to understand..

Would it be possible for me to communicate to the Pijuice using an esp32 maybe through the i2c protocol? Is there a documentation anywhere or it is impossible to do?

I know for use I need a Raspberry to communicate with the Pijuice, but I would like just to get the battery level using Pijuice without the need of implementing a Raspberry. I just wanna do it with an esp32.

is that even possible?

Thank you in advance for your time.

@tvoverbeek
Copy link
Contributor

If you only need the charge level, it can certainly be done with an esp32 using i2c.
The raspberry pi communicates with the PiJuice using I2C.
Look at the pijuice.py source file (https://github.com/PiSupply/PiJuice/blob/master/Software/Source/pijuice.py the GetChargeLevel function at line 182.
You will need to implement the low level i2c communication protocol (with checksums) as in the PiJuiceInterface class at the top of the pijuice.py file.

@uGiFarukh
Copy link

I can share the C code based on Arduino Wire Library on esp32 for collecting almost all the metrics from the pijuice board. I am currently using a combination of esp32c3 and pijuice for one of my projects. So, I have already coded the status functions using the wire library.

@SerinoA9 you can let me know what information you need to retrieve from the pijuice board through I2C, and I can possibly share the code and explain it a bit.

@SerinoA9
Copy link
Author

Guys thanks so much for your answers and time.

@uGiFarukh Thank you in advance for your patience. I am trying to retrieve the battery charing level from the Pijuice through the I2C protocol.
I am currently using a XIAO esp32s3, if you have any code, anything that might help me understand even just the communication between the esp32 and the PiJuice it would be very helpful.

@uGiFarukh
Copy link

Sorry for the late reply @SerinoA9. First make sure you have the SDA and SCL line on the XIAO esp32s3 pulled up with around 10k resistor to 3.3V. Pin D4 and D5.

#define PIJ_ADDRESS_I2C 0x14          /* PiJuice I2C Address */
#define PIJ_CHARGE_LEVEL 0x41         /* Charge Level Command */

typedef struct pij_model_cmd
{
   uint8_t cmd;
   int length;
   uint8_t data[9];
} PiJuiceInterface;

static uint8_t pij_get_checksum(const uint8_t *data, size_t len);
static bool pij_read_cmd(PiJuiceInterface *interface);
static short pij_charge_percent(PiJuiceInterface *interface);

void setup(void)
{
   Serial.begin(115200);
   
   if (!Wire.begin()) (void)ESP.restart();                  /* if something wrong with i2c init, restart esp */
   (void)Wire.setTimeOut(999);                              /* a timeout is always good to have */
   if (!Wire.setClock(10000)) (void)ESP.restart();          /* using a low i2c clock speed for stability */
}

void loop(void)
{
   PiJuiceInterface interface = { 0 };
   Serial.println(pij_charge_percent(&interface));
}

static uint8_t pij_get_checksum(const uint8_t *data, size_t len)
{
   uint8_t fcs = 0xFF;
   for (size_t i = 0; i < len; i++) fcs ^= data[i];
   return fcs;
}

static bool pij_read_cmd(PiJuiceInterface *interface)
{
   volatile byte response = 0x0;

   (void)Wire.beginTransmission(PIJ_ADDRESS_I2C);
   if (Wire.write(interface->cmd) == 0) return false;
   if (Wire.endTransmission(true) != 0) return false;

   response = Wire.requestFrom(PIJ_ADDRESS_I2C, interface->length, 1);

   if (Wire.available() > 0) (size_t)Wire.readBytes(interface->data, interface->length);

   if (response < 0) return false;

   return true;
}

static short pij_charge_percent(PiJuiceInterface *interface)
{
   interface->cmd = PIJ_CHARGE_LEVEL;
   uint8_t checksum = 0x0;
   interface->length = (interface->length + 1);

   if (!pij_read_cmd(interface)) return -1;

   checksum = pij_get_checksum(interface->data, (interface->length - 1));

   if (checksum != interface->data[interface->length - 1])
   {
      interface->data[0] |= 0x80;
      checksum = pij_get_checksum(interface->data, (interface->length - 1));

      if (checksum == interface->data[interface->length - 1])
      {
         interface->length--;
         return interface->data[0];
      }

      return -1;
   }

   interface->length--;
   return interface->data[0];
}

NOTE: These implementations are no way meant for production usage.

@SerinoA9
Copy link
Author

Thank you so much @uGiFarukh.
Really helpful.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants