Author Topic: How can I write to an I2C device from a Web Page?  (Read 2535 times)

matt_vs

  • Full Member
  • ***
  • Posts: 15
    • View Profile
How can I write to an I2C device from a Web Page?
« on: January 15, 2014, 12:43:10 PM »
Hello-

This post is a new thread that evolved from my thread titled - Ethernet to I2C converter

I need to write to an I2C slave device to enable/disable outputs of my power supply -

The last part I have to complete is to get the enable/disable function working.  I need a bit of guidance on how to get there...
In the voltage/current/temp monitoring, the firmware reads the I2C bus and populates the memory and the webpage Java script reads the memory and converts the number for proper display.  I am comfortable with this code now.

For the enable/disable - everything goes the other direction. The only way I see to do this is:

Option #1 - User input from the website needs to go back to a new memory location - Then is there an I2C write function in firmware to read the data from memory and write it to the I2c bus/slave? (I know we use the I2Creadtoarray to read the I2C bus and write to memory)

Option #2 - Place a user input box on the website where the user enters a binary 101100 (for example) that would indicate which outputs to enable/disable.  Then when the user hits the update button that byte of data is written directly to the I2C bus.  I'm not familiar with .html coding to make the update button actually do something and I don't know if we can go directly to I2C or we need to go to memory first and then from memory to I2C.

Once again - I'm looking for some help from you :-) You have really helped me to get this far and I truly appreciate it!
Let me know your thoughts.

Thanks!



modtro2

  • Administrator
  • Hero Member
  • *****
  • Posts: 564
    • View Profile
Re: How can I write to an I2C device from a Web Page?
« Reply #1 on: January 15, 2014, 01:36:06 PM »
Hi Matt! Do you need an enable/disable button for each channel? We can place a "Enable/Disable" button on each row of the current web page. Can you please take a screen shot of the current web page and post it here. I can then suggest where to place the buttons.

Option #1.
Can implement something that sends a command to the SBC66EC, and the I2C comms is than done in the SBC66EC firmware, but option 2 is much easier!

Option #2.
These buttons can send an I2C message directly to the hardware on your board. This is very easy to do in the HTML, just a couple of lines to create a button that sends a command to I2C port 1. See the s - Serial Port Command on the Webserver Commands  page. For example, to create a button that sends "0x55, 0x66" to a slave at address "0xD0" on I2C 1 bus, add following to your web page.
Code: [Select]
<form method="GET" action="index.htm">
<button name="s7" value="D05566">Send I2C Command</button>
</form>
This will send the following command to the SBC66EC board:
s7=D05566

Where "s7" is the command for the I2C 1 port, and "D05566" is the data to send. See Webserver Commands  page for details.

matt_vs

  • Full Member
  • ***
  • Posts: 15
    • View Profile
Re: How can I write to an I2C device from a Web Page?
« Reply #2 on: January 16, 2014, 12:20:01 PM »
Hello-

I do need an enable/disable for each DC output and I have halfway added some buttons to the existing page (see attached).

I am unable to get the code in your last post to do anything to the I2C bus...

I am able to send commands directly through my browser like this:
http://mchpboard/?s7=9A0000    (This sends 0x00 to register 0x00 at address 0x9A)

I am also able to send commands like this:
<a id="led5" onclick="newAJAXCommand('leds.cgi?s7=9A0000');">&bull;</a>
(This is on your index.htm page and when I click on this LED it sends that same command as above)

Anyway - the tricky part is there is one 8 bit register (only lowest six bits are used) that controls 6 of the outputs and one that controls the other six outputs.

Let's just look at 6 outputs for now:
Slave address 0x9A register 0x00 controls six of the DC outputs as shown below:

D7   D6   D5   D4   D3   D2   D1   D0 (data bits from MSB to LSB)(D7 and D6 are not used)
N/A   N/A   V11   V5   V4   V3   V2   V1

A logic 0 turns on the output and a logic 1 turns off the output.  So to turn on all of the outputs I write 0x00 and to turn off all of the outputs a would write 0x3F.

Assuming all outputs are ON - the register contains 0x00
If I want to turn OFF V3 - I would write 0x04 (toggling the D2 data bit)
now to also turn OFF V1 - I would write 0x05 (leaving the D2 data bit high and toggling the D0 data bit)
now to also turn OFF V5 - I would write 0x15 (leaving the previous bits high and toggling the D4 data bit)
to turn V1 back ON - I would write 0x14 (leaving V5 and V3 off and toggling to D0 data bit back to 0)

To disable an individual output:
So V1 = 0000 0001 binary = 1 decimal
     V2 = 0000 0010 binary = 2 decimal
     V3 = 0000 0100 binary = 4 decimal
     V4 = 0000 1000 binary = 8 decimal
     V5 = 0001 0000 binary = 16 decimal
    V11 = 0010 0000 binary = 32 decimal

So if we have a variable called switch1 - when a user clicks disable V1 it would add 1 to switch1 and if they click enable V1 it would subtract 1
Likewise - if they clicked disable V4 it would add 8 to switch1 and if they clicked enable it would subtract 8

Then all we need to do is convert switch 1 from decimal to hex and write it out to the I2C slave to make the outputs change.

I hope this all makes sense - I don't see any other way to make the enable/disable switch clicks change the value of a single bit of an  8-bit byte and toggle the correct bits on and off without affecting the other bits.  Maybe I am making this too complicated....

Please help....  my head hurts from all of this coding and thinking today  :-o

Thanks!



modtro2

  • Administrator
  • Hero Member
  • *****
  • Posts: 564
    • View Profile
Re: How can I write to an I2C device from a Web Page?
« Reply #3 on: January 16, 2014, 07:00:13 PM »
Hi! I just tested the exact code I put on the forum, and adding it to a web page works. Maybe you have to update to the latest v2.03 Beta firmware for the HTTP GET commands (http://mchpboard/?s7=9A0000) to work.

We need some JavaScript bit manipulation functions to set and clear the individual bits. I will add these functions to main.js, and send you the code required for the buttons.

Additionally it will be nice if you could gray the Voltage and Current values for channels that are disabled.

We need a way to get the current value of these two registers in the web browser. If you enable or disable a channel, it will edit the current value, setting or clearing the appropriate bit. Can these registers also be read via I2C? Or, should the firmware on the SBC66EC remember the current value, and make it available via a User Memory byte?

If these registers can be read via I2C, we can issue a "I2C read command" from the web browser requesting these registers be read into "User Memory". On our web page, we can than get the current value of that "User Memory" address, modify it, and use the modified value to write to the I2C register.

matt_vs

  • Full Member
  • ***
  • Posts: 15
    • View Profile
Re: How can I write to an I2C device from a Web Page?
« Reply #4 on: January 17, 2014, 03:49:08 AM »
Good Morning-

Just to clarify -

I have no problem at all sending a serial command via a URL to the SBC66EC-
http://mchpboard/?s7=9A0000    - This works perfectly! I can also write to user memory like this:
http://mchpboard/?u53=FF  - no problem at all:

I just couldn't get the code to send a serial command when a user pressed a button like this:
<form method="GET" action="index.htm">
<button name="s7" value="9A0000">Send I2C Command</button>
</form>

Pressing the button did not send that to the I2C bus.

We definitely need some JavaScript bit manipulation to get the enable/disable functions working correctly.
And it would be AWESOME if we could gray out the Voltage and Current values for the disabled channels.

We can easily get the current value of the two switch registers - they can be read via I2C and I have already added code to the firmware to do that.  I created two one byte user memory locations and the firmware does an I2Cread to memory and populates those locations:

<DIPswitch1>~#u51~</DIPswitch1>
<DIPswitch2>~#u52~</DIPswitch2>

In the firmware I do:
            i2c1BeginTransmission(0x9A);                      //Begin transmission to DIPswitch1
            i2c1Write(0x00);                                         //Write register address for Configuration = 0x00
            i2c1ReadToArray(&userRam[0x51], 1);         //Read 1 byte from DIPswitch1, and save to given pointer
            i2c1EndTransmission();
            waitForI2C = TRUE;                                    //Indicate that we are waiting for I2C to finish current transmission

            i2c1BeginTransmission(0x9C);                     //Begin transmission to DIPswitch2
            i2c1Write(0x00);                                        //Write register address for Configuration = 0x00
            i2c1ReadToArray(&userRam[0x52], 1);        //Read 1 byte from DIPswitch2, and save to given pointer
            i2c1EndTransmission();
            waitForI2C = TRUE;       

I am displaying them on the power page already - see attached screen shot.  You can see that all of the outputs are disabled and the values in Dipswitch1 and Dipswitch2 are 0xFF.  These dipswitch registers are actually eeproms so they remember the last state if they are powered down.  For example - if you have 6 outputs on and six outputs off and you turn off the power supply when you turn it back on the same outputs that were on or off come up that way.  That all happens at the chip level and doesn't need any input from the SBC66EC or the web interface.

So - power on the unit - the outputs come up based on the last values in the dipswitch registers.       (already done)
The firmware then reads those registers and places the values in user memory in Dipswitch1 and Dipswitch2.    (already done)
The JavaScript decodes these hex values and grays out whatever outputs are currently disabled.
Then when a user clicks enable/disable on an output it manipulates the proper bits and directly writes out the new switch value to the switch register.

Sounds easy - but I have no idea how to do the decoding and bit manipulation.  If you could write that code I would really appreciate it!