-
Notifications
You must be signed in to change notification settings - Fork 16
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
Extracting data from output #1
Comments
Hi, this is a very simple solution that displays the traffic only. In my code the processDataBuffer() is the place that processes the communication flow. My code just prints out the characters. This is the place that can be extended with the additional code to identify the address and process the data. I hope this pseudo code can help you. |
I know the logic I need, but not how to achieve it. :) |
I wonder, could it be packed in some sort of a string or so? So it could be sent to a server as it is. |
There is a simple solution and a difficult. Difficult solution is to put the complete command into a sting when all the character is read from the I2C line. This requires more logic implementation into processDataBuffer(). Would the simple solution be enough for you? |
I have modified your sketch to filter specific I2C address, so in the output, I get only an array of bytes I need. That part is OK. Some solution to send it as simple as it can be, would be nice. Later, I could post it here so you can give it a touch or two to make it useful for others. |
That is nice from you. |
Here you are. You may notice a new const volatile byte adresa[ ] In a processDataBuffer function, you will notice all the logic I implemented. It is only basic. Check if there are data with that address, if there is, print it. If not, move on. |
I connected basic PCF8574 with two LEDs on Nano. With ESP32 and ISO1540 I get the expected data. This is the form: S0100000W+10001000+s This should be packed in something like this as a String: S0100000W+10001000+sS0100000W+00001000+sS0100000W+10001000+sS0100000W+10000000+sS0100000W+10001000+sS0100000W+00001000+s |
If I change byte adresa [ ] from 0100000 to something else, I get nothing. On a server, I can easily cut it into pieces and do whatever I want. But first things first. Let's send it. |
thanx for the code. The implemented logic to follow the communication uses interrupts. So here is the thing. In case when there is rare communication and only one or none happens during the delayed loop, then you are lucky and your code works in most of the time. To handle all of this makes it so difficult, if you want to implement the logic in the processDataBuffer(). |
I noticed all the issues a time or two you mention. It is fair enough. On a server, everything can be cut into pieces. And nothing is important that much. If you know what to expect, everything that is not a match, just cut off. The main goal should be to send it to a server. And that is a little bit tricky for me. If you have a solution to take the data from a buffer, no matter what is in it, and put it in a String... |
What is the protocol that the destination server expects? |
HTTPGet request I think if it could be packed in a String, it would be more than enough. |
then the processDataBuffer() should be modified to check if the buffer contains whole S...s pieces and send them via a HTTP GET message. |
I would try to go no matter if any garbage in or not. Is it whole or not. That could be easily filtered on the server. It is not that important if something is missing. Later I will add some other I2C devices, just to see how it works. Or some other I2C expander with 2 ports. To be honest my goal is to monitor some devices that do things in a loop. So if not good in the first reading, it will be in second. Or third. |
In this case it is easy, just make the main loop to send out whatever is in the dataBuffer as a string. For this you just have to modify the processDataBuffer() to put everything into a message string from the dataBuffer and send it out. |
I know that, but not sure how. I am messing up pretty much with putting buffer in a String. Didn't move an inch. That is why I am here. |
I made some modification to make available the sending. Here is the modified code:
#include <Arduino.h> //#define I2CTEST //use it to run a blinking LED test on SDA and SCL pins #define PIN_SDA 12 //BLUE #define I2C_IDLE 0 static volatile byte i2cStatus = I2C_IDLE;//Status of the I2C BUS //v1.1 //////////////////////////// /**
*/
}//END of i2cTriggerOnRaisingSCL() /**
//////////////////////////////// /**
/**
*/
}//END of processDataBuffer() /**
*/
}//END of processDataBuffer() /**
*/ } /////////////////////////////////
}//END of setup /**
}//END of loop |
I hope it helps you. Good luck! |
Nagyon köszönöm! I will try it and let you know. |
Can't compile. This return; |
Maybe the problem is with copy-paste, as you can see. Or maybe better, add a new file in the repo. Besides, this code you posted is not the one I modified with selecting the I2C address. |
The compiler is right (of course :). The return should give back a String, since the value type of the function is String. |
Boldog új évet! No back to the problem. return ""; |
|
Ok, so this code compiles. Problem is, there are empty spaces that I couldn't remove with replace() function. Empty space in a string is not a valid URL. %20 is or no delimiter at all. How to remove that empty space? Or replace it? |
You may notice I added some WiFi code. Not all. |
I put this version into the code base as main-send.cpp |
My bad expression. Sorry. It is New Line that causes the problem. Stay tuned! More tests coming. |
OK. Now the hard part... |
which code do you run that produces this output? Is it the origin code, or some modified? |
Basic sketch from here. |
It would be good to see the beginning of the message flow. The example I can see above has no S and s part to indicate the beginning (S-Star) and the end (s-stop). |
It was a bad wire on SDA2. I fixed that and those 1111 are gone. Now there is still the problem with resets... This is from the middle of the response.
|
Ok, I get the new PCBs With ISO1540, when everything is connected, it works like a charm. When I turn on/off power on the device I sniff, it is ok. No issues. When I do the same on my sniffer, the device I sniff froze. After much testing, I noticed that when I want to do a simple reset of my sniffer, I have to disconnect VCC and I2C lines from the SIO1540, the side of the device I sniff. I tried with some MOSFETs but had no luck. Relays are overkill. |
Just make sure that the power resources of the elements (sniffer, sniffed device and ISO1540) are independent. |
I can see now. The fet2 part causes the trouble. When it is switched of, or the sniffer is down, then SDCL2 and SDA2 lines flies away that causes the trouble for the sniffed device. |
For ISO1540 I made a schematic according to this: While I tested it a lot, I realize I must cut the SDA line when ESP32 is off. I think it can be done with a MOSFET or so. Do you have some suggestions? I am all ears. Edit: |
in my implementation I did not handle the Vcc and GND of the observed side. I just connected the 4 lines (Vcc, GND, SDC, SDA ) of he observed side to the ISO1540 and attached my ESP32 to the other side. If you really want to switch all the four lines then try to find some multichannel low power switch for this purpose. |
There will be times I had to reset or power off the ESP32. In that case, the observed device will just be held in the middle of the loop. That is why I have to cut VCC and now the SDA. For testing purposes, I use MikroE I2C Isolator Click. There is a link few posts above. The problem occurs the same, on protoboard with this Click, and on my PCB with ISO1540 soldered on. Edit: |
I don't have PCF8574. |
I think I know the reason why power off on sniffer side kills the observed side. |
Mate, you have a drink the first time you come to Belgrade! The problem was, that I used MikroE I2C Isolator Click for testing and its schematic for a PCB. But on this click, there were 2 pull-up resistors on the observer side. They cause the problem while testing, and I tried to work around it on my design, not realizing that all I had to do is to remove those 2 resistors. On the PCB I bypassed VCC2, removed pull-ups on the observer side, and it worked as expected. So far so good. No matter, I will order a new revision of the PCB. Hope it will arrive in a week or two. Then, all that is left is the software. It worked last time as it sends the data to a server. But maybe to polish a thing or two. We will see. I will post the schematic here later if some other needs it. |
good news, congrats! |
New boars arrived. That also means new problems... In the previous revision, I had a circuit for switching 3.3V on the ISO1540 (the ESP32 side). I remove it in this newer version. But as SDA is tied on GPIO12 and with 1K on 3.3V it won't boot. GPIO12 is a bootstrap pin and the boot fails if pulled HIGH. On the previous design, 3.3V is there only after I write digital logic on fet pin. There are a few questions... |
Hi, But for some reason it seems that the situation is not the described. Does your observed device works if you switch on only that side and your observer ESP remains off? |
After a bunch of testing with the PCA9535 as it has two ports and is a little bit more complex than the PCF8574, I get some issues. Sniffing works as expected, board too. It looks like the window when the ESP32 takes a picture is small. If I add two 7 seg displays and make it "blink" two numbers it doesn't capture whole segments at the time. Like it takes a capture while it hasn't turned on all segments. For PCA9535 I use an Uno and fire segment after segment in a loop, so it is obvious. Lib works this way. So the question is, how can I make this window bigger? Should it mess the whole thing? The sketch is here: |
my sniffer does not use any window. It is driven by the interrupts generated by the changes on the SDC and SDA lines. This may happen if the WiFi communication is too slow comparing to the i2c data cycles. And also try to put the output to the serial first instead to WiFi. This can help to see if the WiFi communication time it too much comparing to i2c and that is why data gets overwritten after a while. The problem could be that if I2C data is a continuous flow, than after a while it will produce more data than WiFi can send it over and the buffer will fill up and will overwrite the data in it. This will cause that you won't see the complete i2c communication just part of it. |
more explanation Anyway if the I2C communication provides more data than the loop can send it either to the console or to the WiFi channel than it will be overwritten and it also can cause problems too when it writes to a non registered area outside of the reserved buffer. |
Ok. Let's start from the start, shall we?
This is pretty much of an output. This resets the ESP32 after two readings. Additional thing: What do you suggest I do? |
Good news is that we have progress again. The problem is that the sniffer writes faster the data than your program reads it. So after a while the buffer will be overloaded and the program writes data to area that is not allocated for the buffer. So it starts overwrite something, that is why the ESP32 will collapse after a while. The program is not perfect, I did not prepared it for such situation that you have. It can be fixed by pausing the observation, while the buffer is not empty again. What really strange for me is that there is no stop sign in the data flow. I am sure this code would need a revisit, but I have no time at the moment. Meanwhile you could check the I2C protocol and create a parser for the data flow. I cannot help in the DB issue, since I don't know your code. |
After a few attempts, I realize the URI is way too big (414 code). |
Ok, tried with a smaller buffer, and ESP goes into reset all the time. There could be a few solutions.
I think this could be an interesting project for others when finished. I just don't believe I am the only one who needs to spy on one device's I2C lines and get data from it. Edit: |
A usual ESP32 has something like 4Mega byte memory. Filtering the address can help, but this should be implemented. Use POST instead of GET when sending, because GET has the limit. In a few weeks I can start working on the code:
|
I have a working solution for filtering. I have posted it somewhere here, LOL. It would be much easier to just cut all addresses but one. That means I will send to DB only what I need. If I send it all, then I will have to filer it on the server. Much fewer problems to filter it on the ESP. |
You are right saying that it is easier to filter at the source. Anyway I will develop the filter capability that will be optional. I don't see the code you posted. Where is it? |
It is at the top: |
OK, thanks |
I have a proposal for you. Feel free to contact me on dekip[at]beotel.rs |
I tried this sniffer and it works just fine.
My question is:
If I get say, this line in the output buffer
S0100000W+00001000+s
I can see that on the 0100000 address I have 00001000 data. How to take this data for this specific address and do something with it? Maybe send to a server. Do anything.
The reason is, if there are multiple I2C devices, and I want to monitor only specific. So if I get a bunch of those readings and want to filter all of them and take only this one, cut everything and send this 00001000 to a server.
Any help would be appreciated.
The text was updated successfully, but these errors were encountered: