How to use spi to write and read some specfic register address #5053
Replies: 1 comment
-
Posted at 2019-07-22 by AkosLukacs In most modules, there is a r and w function for low level access to the device. I think you can use those. Posted at 2019-07-22 by user101931 Hi AkosLukacs, Thank you for your help. Thank you Posted at 2019-07-22 by AkosLukacs Ooops, missed the SPI part, sorry. For example from the LIS2DH12 that has SPI interface as well (at the bottom of the file):
The interesting part:
Posted at 2019-07-22 by @gfwilliams I think @AkosLukacs has hit it on the head. SPI should be pretty straight forward. The main gotchas are:
If you post the code you have up here we might be able to help you a bit more. Posted at 2019-10-13 by user101931 Hi all, I am fairly new to javascript and Espruino. I just started to implement the SPI, but the code does not seem to recognize my SPI. write function. I think it was because some header files were missing, but I am not sure what and how to include them. Except for the SPI, I am having some trouble finding these function's library function to convert decimal to binary Thank you very much for your time Attachments:
Posted at 2019-10-13 by AkosLukacs You have a typo in the first line: it should be Posted at 2019-10-13 by Robin Sun 2019.10.13
Should also be
This will be of help using the Date functions:
Binary to Decimal, can't go wrong with the tutorials at W3Schools:
Is it possible that SPI is not being used correctly concept-wise? (for read write)
Locate the heading 'constructor SPI' from the 'Reference' page link above and click on the right facing arrow adjacent to that heading. This will link to:
showing that SPI is part of the firmware build and no other 'includes' are needed. Would you provide the link to the source code or tutorial that is being worked from please.
Data byte missing? Chip Select 'Actually' going lo and not inadvertently inverted? Does the Pico MOSI actually go to the inertial device MOSI and not flipped with MISO?
might provide some insight on how I solved communication using the FX2 Logic Analyzer. Saved a ton of time rather than just guessing. . . . Posted at 2019-10-14 by @gfwilliams Hi - I think it might be best to start out from some existing SPI code like http://www.espruino.com/SPI and work from there... The code you've written seems to have a few issues (like For SPI, the issue is you're using In terms of your other stuff - try using the search box at the top right of Espruino.com and specifically the reference at http://www.espruino.com/Reference:
If you want to convert a number to a binary string, just use ... but you don't need to convert anything to binary to send it over SPI
http://www.espruino.com/Reference#fs http://www.espruino.com/File+IO Or since you don't have an SD card, http://www.espruino.com/Reference#Storage
It's literally a function called 'getTime()' - or you can use Posted at 2019-10-19 by Robin Sat 2019.10.19 Hi @user101931, Is the WebIDE right-hand editor panel being used to it's full potential? Make sure the following is *UN-checked* WebIDE >> Settings >> General >> Disable Code Hints When viewing code in that panel when code hinting is enabled, any syntax issue will display a red circle with an 'X' in it. Rollover to gain additional insight. After all code lines syntax check, the use of the debugger; keyword inside functions will allow for additional run-time detail.
It would help us enormously in the future if code snippets could be entered here using the ``` back tick delimiter (Shft ~ ) or highlighting and pressing the < / > code button just to the left of the 'Preview' button in the menu of this edit window.
This will enable us to block copy and test that code snippet! Posted at 2019-11-03 by user101931 Thanks to y'all help, I am making a lot of progress now. The code all seem working, but I am encountering this error "Prompt not detected - upload failed. Trying to recover..." when I run a long while loop in Espruino. I am trying to extract the FIFO data from the IMU(LSM6DSL) continuously for a long time. The data look correct at the beginning but the pattern got messed up after a couple of sets of data and then this error "Prompt not detected - upload failed. Trying to recover..." occurs and the entire program just stops. Figure 1 While loop code Figure 2 Correct data pattern before the first 7th set. The number in the middle indicates the number of data left in the FIFO (2048 is when its full), it seems SPI is reading too slow to catch up the FIFO data generator, but I actually set SPI transmission rate to 10 MHz(max rate that the IMU can torrent), I would expect the SPI speed is sufficient enough. Figure 3 shows the error I am getting and the program crashed. Attachments:
Posted at 2019-11-03 by user101931 I check the setTimeout method in this case based on this link, but due to the project requirement, I would prefer reading the data without any interruption for hours (with setTimeout, the code pause about at around 20s automatically with no error), I am wondering if there is a way to do it without pause the program? Or Does Espruino Pico support this kind of application? Thanks Posted at 2019-11-03 by Robin Sun 2019.11.03
@user101931
It appears the Tutorial > ' I am wondering if there is a way to do it without pause the program?' Would a better tutorial assist here?
From #11
Is hardware or software SPI in use?
"Prompt not detected - Upload failed" Was code on the Right-hand editor side of the WebIDE being uploaded while the * while{} * loop was still executing? EDIT: > After thinking this through, I believe the while loop is executing faster than the SPI send-response can keep up. Using setInterval() instead of the loop would be a better practice. See the data collection logging tutorial link above.
In the code block in #11, variable start is never re-evaluated or re-assigned. Loop execution would be unpredictable. Infinitely fast looping until 20 seconds have elapsed. Also in line tm = readtime() the function definition is not present. Please upload *all* code using the following:
I placed instructions for easy code insertion within each post at the end of #10. Including that way will allow us to block copy your code and comments from hilighting using Ctrl+C right here in the forum edit window. We would have line numbers to reference as well. Would greatly assist us. Posted at 2019-11-04 by user101931 Hi Robin, Thank you very for replying and helping. I set them to setInterval and that error does not occur anymore. I believe I am using the hardware SPI and this is my SPI set up
The read time is to read the timestampes from the IMU, which is part of the data collection from the IMU.
I checked the time needed to collect one set of data is fixed at .029ms, IMU generate each set of data at 833Hz = 1/833 ~=0.0012, the time for the IMU to generate one set the data is a lot faster than the program excution. I think the problem is when the FIFO is full, the pattern will be messed up. I am not very sure why PICO takes so long to read a set of data. I tried to look up the default system clock rate and it seems 84MHz already based on this E.setClock(Correct me if I am wrong), is there a way to improve the program execution/reading speed? Changed version code
Output:
Spi:
Posted at 2019-11-04 by AkosLukacs I don't know the maximum speed of the Pico, but UART may be a bottleneck. I haven't used that IMU, but looks like you can read multiple bytes in a single operation. That definitely will be faster. The number of characters you execute has a direct effect on execution speed. For example
is almost surely faster than
Related to that, Posted at 2019-11-05 by Robin Mon 2019.11.04 Thank you for posting the upgraded snippets @user101931
> 'I believe I am using the hardware SPI ' Yes. Based on the setup function snippet, as there isn't an assignment to a var used to declare the software SPI pinout such as
and the use of Espruino defined SPI1 SPI2 SPI3 hardware constants. The following reference from image 3 from #14 I like the new I do see a possible area of contention. L18 has an argument (the value of the interval parameter) for My S.W.A.G. guess is that the decimal value is getting rounded to an integer, and that is still too small a value in an attempt to fetch the SPI payload. Shouldn't this be more like a sampling request every second or so, and the SPI traffic from the device would then be able to respond timely? This is akin to having an attempt to fetch that is 100-1000 times faster than the data that actually is attempted to be fetched. The requests are queueing up and eventually running out of room/time to perform the actual task. As I said, just a quick S.W.A.GG'd response. That would explain why a few accurate lines of data do in fact get through, then the whole works gets bogged down. *(I'll have more time to dig deeper this weekend)* > for @AkosLukacs
One reason might have been to enable the debugger to return a value for human viewing, before actually returning that value. I fall victim to that requirement and sometimes overlook and catch during code cleanup. Point well taken though. Posted at 2019-11-06 by Robin Tue 2019.11.05 @user101931
To help us better visualize the actual duration, modify the extraction() function by commenting out the other lines, such that only one line is executed and lets time that to see what the actual duration is. Something like:
It would be nice if a table of duration times could be generated for each of the vars there. This would give us an idea of where the bottleneck might be. Posting the code for function read_FIFO() might assist here, and it may be timing for the guts of that function might be needed also, if the duration test(s) above are much greater than several msec. To show the delay using the embedded console.log() statement is taking, place a single console.log() statement beside the var being tested and run two tests, the other commenting out the log() statement. It is likely that continuous writing to the Left-Hand console side is bogging down the works. Your test will help us identify. Posted at 2019-11-07 by user101931 Hi Robin and AkosLukacs, Thank you for taking your time helping me. Here is my code and output for measuring one read_FIFO, (compare with 1/833Hz = 0.0012s). I just realized getTime() was actually returning million seconds (Correct me if I am wrong), the speed is actually very fast if the value that return is ms. (500-1000 times fast than the data generated). I am concerning if that's my IMU's configuration, I will double-check that. However, when I decrease the speed to 52Hz or 26 Hz, the data was actually generated properly. and when I optimize the code, a couple more correct data set will appear before it gets messed up. Not really sure what might be the issue now.
And the corresponding output is:
Enable extraction and disable read_FIFO() in the code
The code to run one complete extraction() with no print
Output
Here is my read_FIFO code, I am calling two SPI_read in this function, FIFO_DATA_OUT_H/L are two registers to store the generated FIFO data
Thank you very much. Posted at 2019-11-08 by Robin Thr 2019.11.07 My DISCLAIMER from #16 still applies, Hi @user101931, a quick cursory peek implies the SPI part of the code is working as it should. The timing values don't appear out of range. I'll do a math check this weekend. > 'a couple more correct data set will appear before it gets messed up' What isn't shown is the repeating part. Would you please post the setInterval() line of code. Although not absolutely needed, but . . . It would help immensely if you could also provide a timing check on just single individual lines, so that some quick mental cross checks could be performed.
> 'I just realized getTime() was actually returning million seconds (Correct me if I am wrong)' There are a few links in other posts within this thread, searching w3schools.com and MDN developer.mozilla.org should allow the discovery of that answer. If you are still stuck, please post the final links where discovery ends, and I'll do some digging after that. I'm sure the learning how to find those links will enhance the discovery process and boost your ego. ;-) When successful, please post the link for future enthusiasts reading this thread. Thanks. I'll have a bit of time to dig into this over the weekend. Is this the datasheet for the device? Posted at 2019-11-10 by user101931 Hi Robin, Thank you for helping me so much Sorry if I misunderstand, I am not so sure how to measure the repeated part if you mean measure how fast the interval is running. I put the measure time in the all read_FIFO, read_Normal, and read_Time and this is my output
and the code looks like this
ss
I believe the time I measure is in millisecond, and I also measure the clock frequency of the SPI is running correctly at 10 MHz, so I think both system and SPI should techninilly running fast enough? and thank you again : ) yes, that is the IMU datasheet. I configured FIFO as continuous mode so I can keep the data from the IMU with a set timestamp and it can keep running for hours. The goal is to do the data collection at 833 Hz for hours and the output timestamps gap should be fixed (increment by 48 or 49 each timestamp). The FIFO mode provides the correct data but I have to reset every time to get the new set of data since it will stop filling after it full. The reset process result in missing some data, so it is not very ideal Attached is the SPI clock frequency measured from the oscilloscope Attachments: Posted at 2019-11-10 by Robin Sat 2019.10.44 For L2
Three msec is about what I see with other devices using SPI
Are you still getting errors with the above? A typical value for the duration would be 2 to represent 0.002, but my belief is that is still too small. I would expect a value around 50+ Try So my guess is that we need to look at how the request for data is made, not the actual transfer of data that seems to be returning accurate values. If setInterval() which needs to be in msec is changed to a value of 100-2000 does the error after around eight or so iterations still occur? Was the datasheet link in #19 accurate? Posted at 2019-11-10 by Robin
Would you point to a page within the datasheet, that suggests using that frequency or range of frequencies for your use. When I read over, my interpretation of how to request data was a bit different. How are the gyro, or accelerometer used? It might be that your requirement is different than I envision. Are you picking up the device from a stationary position and expecting the Espruino device to respond to that input? p. 35 of datasheet Are we in 'continuous' mode? Is so, the FIFO buffer is probably filling up before each data item is removed from the buffer and the device is cramming in bytes until errors in output are seen. Could this be a possibility? How often do you actually need the data, the device outputs? It seems that it is desired in the msec range, but my interpretation is that reading those values should be in the many tens of msec range, say every half second or so. Posted at 2019-11-10 by user101931 I just tried setInterval(extraction,150);
Oh sorry, on page 57/114 FIFO ODR can be 833Hz frequency range from 12.5 to 6.6kHz. so we choose 833Hz because it is a nice frequency for the algorithm that we are developing for processing the data Posted at 2019-11-10 by Robin May I ask which time zone you are in? I'm in CST 6 hours behind GMT. Getting a bit late for me, so trying to make a determination of how long I might choose to hang in there this evening. Did you see the code example at: > http://www.espruino.com/LSM6DSL Have you tried using It's not clear to me yet how the device is desired to be used and what data is required. Posted at 2019-11-10 by user101931 Haha, no problem. I am in the mountain time zone Posted at 2019-11-10 by Robin Let me get another Whiskey, and I'll read over that page ref Just grabbed 'Old Ezra #7' Bourbon 101 proof. Love the stuff. Neat. Posted at 2019-11-10 by user101931 I will integrate the gyro over that time period, so I think I will every single set of data that output at 833Hz, "Is so, the FIFO buffer is probably filling up before each data item is removed from the buffer and the device is cramming in bytes until errors in output are seen. Could this be a possibility?" I think this is possible. but if this is true, wouldn't it make it very hard to pull the data in high frequency? Haha have a good time Posted at 2019-11-10 by Robin Just read over p.57 Have you tried just reading a single set of values while 'NOT' in continuous mode? My gut feel is that the device is responding with an accurate data payload to a request, so the SPI part seems to be working as it should. From all the data sets posted, it seems there is an issue while in continuous mode. What are the expectations of the gyro/accelerometer? How is it expected to be used? Posted at 2019-11-10 by Robin What is being used as the trigger to fetch the data? Is it the movement of the device, or is it human input, via a switch perhaps? > 'I think this is possible. but if this is true, wouldn't it make it very hard to pull the data in high frequency?' Your data posts, show that it is possible to fetch data reliably at 4 msec 0.004 as the timing is around 0.003+ and that seems a good value based on other devices I have used. So, is 200+ samples per second what is needed in your design? It certainly seems doable, and my gut feel is that the Javascript engine will be able to keep up at that demand. What isn't clear is what is needed in the design.
While anything goes, aren't accelerometers polled at say a tenth second interval, then acted upon when that duration is exceeded? Posted at 2019-11-10 by user101931 The FIFO mode provides the correct data but I have to reset every time to get another round of FIFO data, since it will stop filling after it full. The reset process clear everything that might stall in the FIFO and results in missing some data (because timestamp incremented a lot ), so it is not very ideal So ideally, I would like to save the program in flash memory in Epsurino, and when I supply the power to Epsurino or turn on some switch, it will start to fetch data So this is how I would use those data: For now, So I would prefer to integrate every set of data at every 833Hz = 0.0012s I just realized you edit #24 I am gonna look at those links now Posted at 2019-11-10 by Robin Yes, you are correct, our edits are stomping on each other. Maybe I'll slow down on the Bourbon. . . . . Not!
As your tests show, a data fetch over SPI is taking 0.003+ sec, so that confirms your preference won't be possible. Are you attempting something like the Wii controller would need as real-time input? Just trying to get an idea of why so much data in such as short period of time is required. Posted at 2019-11-10 by user101931 Haha ^ ^ and I thought gettime() returns in ms. Isn't 0.003 is in ms? Posted at 2019-11-10 by Robin Ahhhhh, we are on to something. Yes. 0.003 is a value that represents msec. But the Experience tells me though, as you approach below 20 for instance, that the time to interpret EDIT:
Check out the link in #29 Inline 'C' will speed things up. But I don't know if it will solve your specific issue. Posted at 2019-11-10 by user101931 I just tried 3 and it looks like the same output as 0.02 that I have before is there a way to check the data without using print? and another way to call the function repeatedly if we want to call it fast? for visualizing the data, one other method I can think of is writes file, I believe the write file should be faster than console.log(), but I am concerning if write file write it to the flash memory? if so, i am afraid I do not have enough flash for the data in espruino . Yes, I will try that inline c, I tried the one with adding "complied" in the code and it did not work, but does increase a bit speed. OHHHHH no, if gettime return in second, that proof the 833 Hz is impossible with javascript Posted at 2019-11-10 by Robin Sun 2019.11.10 Good Morning @user101931 ran out of steam last evening as I'm an hour ahead.
Wanted to make sure it was understood that adding the The time killer is the actual use of > 'is there a way to check the data without using print?' Q: Is it really necessary to make an attempt to print *ALL* the values to the console? While it might be necessary to sample at a high rate, the data really isn't changing that fast between samples. My S.W.A.G. guess is that more than 90% aren't even needed as human perception is at a much slower rate. Isn't the need just to determine when the accelerometer changes state? What about using a counter and a conditional statement to say log every twentieth pass, instead of every pass? What about only fetching data when say the device is bumped for instance?
Other than a while loop, which will be tough at times to break out of, (not recommended stick with setInterval) writing the loop with inline 'C' will remove the interpreter having to read and parse each Javascript line of code. > 'but I am concerning if write file write it to the flash memory?' Some ideas from the data logging tutorial to toss around:
Posted at 2019-11-19 by @gfwilliams Sorry I'm a bit late to this. Basically Espruino's JS execution speed isn't that fast because it's interpreted. Looking at the code I've seen I think there are a few things you could do to really improve speed:
Because you're doing the same command over and over, you can also use bind which basically works out the arguments and creates a new function that contains them. Here's some code that should be pretty fast
But I'm struggling to see the complete code you're using at the moment so I can't be sure this will do exactly what you want. Using the same form you should be able to modify it to do what you need though. Posted at 2019-11-19 by @gfwilliams Just to add to this...
Could you just write the data to a global variable? Then when you want to check it you can write 'print(mydata)'? Posted at 2022-04-13 by user142686 setTimeout() and setInterval() functions allow you to execute a piece of JavaScript code/function at a certain point in the future. setInterval repeats the call, setTimeout only runs it once. JavaScript setTimeout(expression, timeout); runs the code/function once after the timeout. It is a time based code execution method that will execute script only one time when the interval is reached, and not repeat again unless you gear it to loop the script by nesting the setTimeout object inside of the function it calls to run. If geared to loop, it will keep firing at the interval unless you call clearTimeout(). If you want something to happen one time after some seconds Then use setTimeout... because it only executes one time when the interval is reached.
setInterval(expression, timeout); runs the code/function repeatedly, with the length of the timeout between each repeat. It is a time interval based code execution method that has the native ability to repeatedly run specified script when the interval is reached. It should not be nested into its callback function by the script author to make it loop, since it loops by default. It will keep firing at the interval unless you call clearInterval(). If you want to loop code for animations or clocks Then use setInterval.
|
Beta Was this translation helpful? Give feedback.
-
Posted at 2019-07-22 by user101931
Hi
I am trying to use Espruino Pico to extract data from the IMU(LSM6DSL). In order to configure the IMU, I need to configure by writing and reading the value to the register. However, from the espruino library, I am not very certain how to write and read the value to the IMU registers. I am wondering if anyone has done something similar? Thank you very much for your help.
Beta Was this translation helpful? Give feedback.
All reactions