Comments (2)
There are actually two types of handlers, which is what causes the confusion I think. There are handlers for 'normal' commands, like "report analog pin", "report digital port" and "report version". And there are also handlers for sysex-commands, like "report firmware". The difference is that the former take a specified number of arguments (usually two, a least and most significant byte, to be able to define numbers higher than 256) and the latter take any number of arguments, as everything is read until the END_SYSEX bytes comes along. See the iterate method for how this works.
So if you want to define a non-sysex handler, use the args you need. If you define a handler for a sysex command (which you probably want to do for custom commands), you can do the same if the number of arguments is fixed, or use *data
as in the _handle_report_firmware
handler.
Looking at it now, I might split the handler in two types later (sysex/non-sysex) as that looks a little clearer.
About moving towards 2.2/2.3, I think the only thing really needed is implementing the remaining sysex commands for capabilities querying and the like. But it might include some refactoring to make this easier. I will probably look at this next week.
from pyfirmata.
Thanks for taking the time for such a detailed reply. This information should be more than enough for me to put together my code examples.
In particular I'm aiming to write logic on both sides of the connection which permits the marshalling and unmarshalling of canonical Arduino data types (based on 8-bit), into a 7-bit transport, as per the code below in Arduino, and the equivalent code in python below that. Please note these code blocks have not been tested, but in some ways code is its own best description.
/** Symmetric with decodefrom7 - encodes bytes to 7-bit values, with an overflow byte
* to store extra bits. Returns the number of total bytes written to the destination byte array*/
int encodeTo7(byte* srcBytes, byte* dstBytes, int srcCount){
byte overflowByte = 0;
byte overflowPos = 0;
int dstPos = 0; //current writing position in dst array
for(int srcPos = 0; srcPos < srcCount; srcPos++){
//store msb in overflowByte, filling bits from left, shifting one extra to avoid msb
overflowByte |= (srcBytes[srcPos] & 0x80) >> (overflowPos + 1); //store msb in overflow byte using next free position
overflowPos++; //update overflow write position
//passthrough the 7-bit truncated byte filling destination array from left
dstBytes[dstPos] = srcBytes[srcPos] & ~0x80; //write the 7 allowed bits (zeroing the msb)
dstPos++;//update destination write position
//write overflow byte to stream when it's full or stream is ending
if(overflowPos == 7 || srcPos == srcCount-1){ //byte full or stream ended
dstBytes[dstPos] = overflowByte; //write the 7 allowed bits
dstPos++; //update destination write position
overflowByte = 0; //reset overflow byte
overflowPos = 0; //start writing from beginning again
}
}
return dstPos;
}
/** Should be symmetric with encodeTo7(). It populates the specified number of output bytes by reading
* 7 bits from each source byte and retrieving the extra bit from a 7-bit overflow byte which is written after
* after each frame of 7 bytes (with the final frame potentially being less than 7 bytes). */
void decodeFrom7(byte* srcBytes, byte* dstBytes, int dstCount){
int srcPos = 0;
int partialFrameLength = dstCount % 7; //find out number of bytes stored in last frame (remainder from frames of 7)
//int srcCount = ((dstCount / 7) * 8) + (partialFrameLength == 0 ? 0 : partialFrameLength + 1); //count of source bytes needed
int overflowPos = 0; //keeps track of the next overflow bit to read from the overflow byte
for(int dstPos = 0; dstPos < dstCount; dstPos++){
//get the 7 bits from the current byte, and reconstruct the final bit from the overflowbyte
int frameLength = dstPos + partialFrameLength < dstCount ? 7 : partialFrameLength; //frame length (not including overflow byte)
dstBytes[dstPos] = srcBytes[srcPos] | ((srcBytes[srcPos - overflowPos + frameLength] << (1 + overflowPos)) | 0x80); //read extra overflow bit from predictably offset overflow byte
//(srcPos - overflowPos is the start of the frame)
overflowPos++; //update overflow read position
srcPos++; //update src read position
if(overflowPos == 7){
overflowPos = 0;
srcPos++; //update read position to skip the overflow byte
}
}
}
# returns the bytes encoded see canonical Arduino code for comments - this is a python port
def encode7(srcbytes):
dstbytes = array()
overflowbyte = 0
overflowpos = 0
dstpos = 0
for(srcpos, srcbyte in enumerate(srcbytes):
overflowbyte |= (srcvalues[srcpos] & 0x80) >> (overflowpos + 1)
overflowpos += 1
dstbytes.push(srcbytes[srcpos] & ~0x80)
dstpos += 1
if(overflowPos == 7 || srcPos == srcCount-1):
dstbytes.push(overflowbyte);
dstpos += 1
overflowbyte = 0
overflowpos = 0
return dstbytes
# returns the bytes decoded, see canonical Arduino code for comments - this is a port
def decode7(srcbytes, dstcount):
dstbytes = array()
srcpos = 0
partialframelength = srcbytes.length mod 8
if(partialframelength != 0):
partialframelength -= 1
overflowpos = 0
for(dstpos in range(dstcount)):
framelength = 7 if (dstpos + partialframelength < dstcount) else partialframelength
dstbytes.push(srcbytes[srcpos] | ((srcbytes[srcpos - overflowpos + framelength] << (1 + overflowpos)) | 0x80))
overflowpos += 1
srcpos += 1
if(overflowpos == 7):
overflowpos = 0
srcpos += 1
return dstbytes
from pyfirmata.
Related Issues (20)
- Tone and Notone functions from Arduino
- HC-SR04 or PulseIN
- Problem with the method ping()
- Does it have any kind of unit testing?
- problem in running a RGB Led with pyfirmata
- Why does the pyfirmata closes after a certain amount of time running?
- Steps for PWM in pyfirmata
- How to get 20kg servo working in pyfirmata HOT 2
- documentation enhancement request: How to use a newly defined board layout dict?
- python 3.10.5 HOT 1
- Save data with analog read
- ImportError HOT 2
- inspect.getargs - Not available in Py 3.11 - Replace with inspect.getfullargspec HOT 6
- Error obtaining data when multiple sensors at the same time are used on a ArduinoUno
- AttributeError
- (python 3.x) ImportError: no know parent package
- Import "pyfirmata" could not be resolved
- Sending text to display no longer working? < board.send_sysex( STRING_DATA, util.str_to_two_byte_iter( text ) ) > HOT 1
- Communicating with I2C module
- Pyfirmata not working but there are no errors HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from pyfirmata.