Read bit stream from a Serial Interface
-
- Posts: 9
- Joined: Thu Dec 22, 2016 10:15 pm
Read bit stream from a Serial Interface
Hi all!
I'm facing a problem with serial communication with the MicroPython board.
I have a digital sensor that outputs data to a Synchronous Serial Interface (SSI) according to a protocol that's shown in the figure below:
As you can see from this datasheet https://ams.com/ger/content/download/43 ... _EN_v2.pdf the reading of the value is init by an high impulse on a sensor pin and after a period of time (which is written in the datasheet) the sensor starts to output values on the serial line.
Any subsequent reading of the value are init in the same way.
The problem is that this particular protocol is not coded in any MicroPython class, because it's not SPI nor UART nor I2C or any other protocol which is included with MicroPython distribution.
My question is: do I have to make a pyb module or can this task be achieved with only MicroPython?
Further more, I need to know how to give the sensor the CLK, is there any pin on the Micropython? Can I do this with Pythonor do I have to create a module?
If the C module is the only way, can you please point me some documentation on how to do this?
Thanks a lot for your precious help!
Giacomo
I'm facing a problem with serial communication with the MicroPython board.
I have a digital sensor that outputs data to a Synchronous Serial Interface (SSI) according to a protocol that's shown in the figure below:
As you can see from this datasheet https://ams.com/ger/content/download/43 ... _EN_v2.pdf the reading of the value is init by an high impulse on a sensor pin and after a period of time (which is written in the datasheet) the sensor starts to output values on the serial line.
Any subsequent reading of the value are init in the same way.
The problem is that this particular protocol is not coded in any MicroPython class, because it's not SPI nor UART nor I2C or any other protocol which is included with MicroPython distribution.
My question is: do I have to make a pyb module or can this task be achieved with only MicroPython?
Further more, I need to know how to give the sensor the CLK, is there any pin on the Micropython? Can I do this with Pythonor do I have to create a module?
If the C module is the only way, can you please point me some documentation on how to do this?
Thanks a lot for your precious help!
Giacomo
Re: Read bit stream from a Serial Interface
This looks vaguely like I2C. You might check the details, it might be actual I2C (also called IIC or TWI), but they avoid calling it by name because there were trademark and patent issues with it.
Otherwise, you should be able to read that with the SPI peripheral.
Otherwise, you should be able to read that with the SPI peripheral.
Re: Read bit stream from a Serial Interface
You can create the signals CSn, CLK in Python and read also the data back, since the device has no restriction on slow reading. The clock raze that can be achieved depends on the code generator used. Using viper code, about 1 MHz could be possible.
-
- Posts: 9
- Joined: Thu Dec 22, 2016 10:15 pm
Re: Read bit stream from a Serial Interface
Thank you all for your precious support!
Once I get the sensor to work properly, I'll try with Python!
Maybe a stupid question: what is Viper code? It is something related with programming or is it actual coding language or paradigm?
Thanks again for your precious help!
Once I get the sensor to work properly, I'll try with Python!
Maybe a stupid question: what is Viper code? It is something related with programming or is it actual coding language or paradigm?
Thanks again for your precious help!
Re: Read bit stream from a Serial Interface
Viper is a function decorator, which causes the python compiler of the device to use a code emitter, which generates effective native machine code. It supports a language subset only, but for bitbanging tasks thsi is very useful. Look here:
http://docs.micropython.org/en/latest/p ... ight=viper
http://docs.micropython.org/en/latest/p ... ight=viper
-
- Posts: 9
- Joined: Thu Dec 22, 2016 10:15 pm
Re: Read bit stream from a Serial Interface
Hi all again!
I tried to connect the sensor to the MicroPython and it actually works for sensing the angle.
The problem starts when I need to read speed (so differential measurements).
Right now the pyboard needs something like ~400 us to read an angle measure, and this is lower a lot the rate in which I can read speeds.
I tried to use the viper decorator, but it doesn't help much.
I think I'm doing wrong something, since I use the out pin to generate manually the clk signal and I think that there's should be a better approach (maybe using interrupts? I dunno).
This is the code I used to decode the angle from the Serial Interface.
As you can see, the read() method make the CLK pin to to oscillate.
I'd like to read it more quicly, it would be optimum to reach the 1MHz threshold! Btw, where is the bottleneck? Is writing or reading a Pin a time consuming operation?
I set the frequency of the Pyboard to the higher value, too, but it didn't help much!
Other than that, since for my use-case (designing data acquisition for a Formula-style car) I need a lot of speed (in the sub-millis range), is there something you can suggest me for reaching this goal?
Thank you a lot, I hope to give back something to the community sooner or later! (Hopefully sooner!)
Giacomo
I tried to connect the sensor to the MicroPython and it actually works for sensing the angle.
The problem starts when I need to read speed (so differential measurements).
Right now the pyboard needs something like ~400 us to read an angle measure, and this is lower a lot the rate in which I can read speeds.
I tried to use the viper decorator, but it doesn't help much.
I think I'm doing wrong something, since I use the out pin to generate manually the clk signal and I think that there's should be a better approach (maybe using interrupts? I dunno).
This is the code I used to decode the angle from the Serial Interface.
Code: Select all
@micropython.viper
def read(self):
self.csn.value(0)
pyb.udelay(1)
self.clk.value(0)
pyb.udelay(1)
angle_array = [0 for i in range(0,18)]
init = pyb.micros()
for i in range(0,18):
self.clk.value(1)
#pyb.udelay(1)
angle_array[i] = self.do.value()
self.clk.value(0)
#pyb.udelay(1)
end = pyb.micros() - init
print(end)
self.csn.value(1)
self.clk.value(0)
return angle_array angle_array
I'd like to read it more quicly, it would be optimum to reach the 1MHz threshold! Btw, where is the bottleneck? Is writing or reading a Pin a time consuming operation?
I set the frequency of the Pyboard to the higher value, too, but it didn't help much!
Other than that, since for my use-case (designing data acquisition for a Formula-style car) I need a lot of speed (in the sub-millis range), is there something you can suggest me for reaching this goal?
Thank you a lot, I hope to give back something to the community sooner or later! (Hopefully sooner!)
Giacomo
Re: Read bit stream from a Serial Interface
Use the SPI peripheral.
- pythoncoder
- Posts: 5956
- Joined: Fri Jul 18, 2014 8:01 am
- Location: UK
- Contact:
Re: Read bit stream from a Serial Interface
You may get some improvement if you cache the bound variables in locals:
That may save time with the self lookups (unless Viper has already optimised this away). Other than that I'm not sure there's much more that can be done with the bit banging loop other than using a built-in peripheral interface if this can be persuaded to work.
As a general point I'd allocate the array outside the function as a global or bound variable: this would make read() run a bit quicker and reduce garbage collection.
The more radical options for the loop are writing a C module or using the built in ARM Thumb assembler. I'd go for the latter to avoid modifying the firmware, but that's just a personal preference.
Code: Select all
def read(self):
clk = self.clk
csn = self.csn
do = self.do
csn.value(0)
As a general point I'd allocate the array outside the function as a global or bound variable: this would make read() run a bit quicker and reduce garbage collection.
The more radical options for the loop are writing a C module or using the built in ARM Thumb assembler. I'd go for the latter to avoid modifying the firmware, but that's just a personal preference.
Peter Hinch
Index to my micropython libraries.
Index to my micropython libraries.
Re: Read bit stream from a Serial Interface
If using the SPI module works, like suggested by @deshipu, that's truly the most elegant way. Using viper modules, you can access the port registers directly. That takes about twice the time than directly using assembler, but still as fast as you can get anyhow with the I/O section of the controller. You'll find code samples for PyBoard in this file:https://github.com/robert-hh/SSD1963-TF ... /TFT_io.py
-
- Posts: 9
- Joined: Thu Dec 22, 2016 10:15 pm
Re: Read bit stream from a Serial Interface
Thank you guys for your help, really appreciated!
I don't think that the SPI solution would work, since it seems to me that the two interfaces are different, but I think I'll have a try.
The solution seems promising, since that way I'll have a lot more control over the clock duration (for example) and for accessing the GPIO, so I'll definitely give it a try!
As @Roberthh suggested, the TFT controller is very useful since it uses both the and decorators and since I think I'm going to use both (preferably the ARM Thumb, since it guarantees more speed which is actually what I want) it would be a really good source of inspiration!
Another question: do you know if it is possible to access any of the ADC through viper o asm_thumb? Since I have to improve the performance of a code which gets the values from 2 ADC!
Thank you again for your help again! Really, really appreciated!
I don't think that the SPI solution would work, since it seems to me that the two interfaces are different, but I think I'll have a try.
The
Code: Select all
@micropython.asm_thumb
As @Roberthh suggested, the TFT controller is very useful since it uses both the
Code: Select all
@micropython.viper
Code: Select all
@micropython.asm_thumb
Another question: do you know if it is possible to access any of the ADC through viper o asm_thumb? Since I have to improve the performance of a code which gets the values from 2 ADC!
Thank you again for your help again! Really, really appreciated!