Raspberry pi adc: MPC3001 using python and spidev - python

I am trying to use a MPC3001 ADC with the Raspberry pi over SPI using Python.
While doing so I am getting some strange results:
The code I am using:
import sys
import spidev
spi = spidev.SpiDev()
spi.open(0,0)
def readAdc(channel):
r = spi.xfer2([1, 8 + channel << 4, 0])
return ((r[1]&3) << 8) + r[2]
while True:
print readAdc(0)
time.sleep(0.5)
running the script above, while measuring the center point of a voltage divider, yields a random switching between 2 values: 504 and 1016.
Since 504 is the value I would expect to be correct, in combination with the binary representation of the two results;
504 --> 00111111000
1016 --> 01111111000
I assume I am accidentally 'creating' a 1 somewhere.
Can someone point me in the right direction.
Thanks in advance
BTW: Is it me, or is there no decent documentation for the spidev lib?

In the data sheet figure 5-2 it shows what the issue is. The data returned from the device, bit by bit, looks like this (where X = don't care, and Bx is bit number x of the data; B0 is LSB and B9 MSB):
BYTE0: X X 0 B9 B8 B7 B6 B5
BYTE1: B4 B3 B2 B1 B0 B1 B2 B3
BYTE2: B4 B5 B6 B7 B8 B9 X X
If you change the return statement to this:
return ((r[0] & 0x1F) << 5) | ((r[1] >> 3) & 0x1F)
it might work.
But if I were you I wouldn't trust me (I no longer have a hardware setup where I could test anything). I think it's best to print the individual values of the bytes in r and ponder the result until it starts to make sense. Be aware that some SPI implementations let you read in the data on either the rising or the falling edge. If you have that wrong your data will never make sense.
Another clue here is that the three LSBs of an A/D converter reading shouldn't be consistently 000, for reading after reading. There is almost always noise in the least significant bit, at least, if not two or three bits.
BTW I agree with you about spidev. I switched to quick2wire and then things went much more smoothly. It's better written and much better documented.

Related

rand and rands implementation in python

I need an implementation of rand and rands from c++ in python to re-encrypt a bunch of files. But can't seem to get it right.
I have a exe that un-encrypts a file into text, I also have to source code, after editing the file I need to encrypt it using the same method.
Since I don't know how to write c++ code, I opted to write in python. Trying first to decrypt it to know the method is the same.
The following code is the c++ code that un-encrypted the files, where "buff" is the beginning of the encrypted block and "len" length of said block.
static const char KEY[] = "KF4QHcm2";
static const unsigned long KEY_LEN = sizeof(KEY) - 1;
void unobfuscate(unsigned char* buff, unsigned long len) {
srand((char)buff[len - 1]);
for (unsigned long i = 0; i < len - 2; i += 2) {
buff[i] ^= KEY[rand() % KEY_LEN];
}
}
From what I understand it takes the last character of the encrypted block as the seed, and from the beginning every 2 bytes it xors the value with an element of the KEY array, this index is determined by the remainder of a random number divided by the KEY length.
Searching around the web, I find that c++ uses a simple Linear Congruential Generator that shouldn't be used for encryption, but can't seem to make it work.
I found one example of the code and tried to implement the other but either don't seem to work.
#My try at implementing it
def rand():
global seed
seed = (((seed * 1103515245) + 12345) & 0x7FFFFFFF)
return seed
I also read that the rand function is between 0 and RAND_MAX, but can't find the value of RAND_MAX, if I found it maybe random.randrange() could be used.
It can also be the way I set the seed since it seems in c++ a char works but in python I'm setting it to the value of the character.
Here is what I observe when un-encrypting the file using the various methods. This is just the first 13 bytes, so if someone needs to check if it works it is possible to do so.
The block ends with the sequence: 4C 0A 54 C4 this means C4 is the seed
Example encrypted:
77 43 35 69 26 6B 0C 6E 3A 74 4B 33 71 wC5i&k.n:tK3q
Example un-encrypted using c++:
24 43 6C 69 63 6B 49 6E 69 74 0A 33 34 $ClickInit.34
Example un-encrypted using python example:
1A 43 7E 69 77 6B 38 6E 0E 74 1A 33 3A .C~iwk8n.t.3:
Example un-encrypted using python implementation:
3C 43 73 69 6E 6B 4A 6E 0E 74 1A 33 37 <CsinkJn.t.37
I can also have something wrong in my python script, so here is the file in case it has any errors:
import os
def srand(s):
global seed
seed = s
def rand():
global seed
#Example code
#seed = (seed * 214013 + 2531011) % 2**64
#return (seed >> 16)&0x7fff
#Implementation code
seed = (((seed * 1103515245) + 12345) & 0x7FFFFFFF)
return seed
KEY = ['K','F','4','Q','H','c','m','2']
KEY_LEN = len(KEY) - 1
for filename in os.listdir("."):
if filename.endswith(".dat"):
print(" Decoding " + filename)
#open file
file = open(filename, "rb")
#set file attributes
file_length = os.path.getsize(filename)
file_buffer = [0] * file_length
#copy contents of file to array
for i in range(file_length):
file_buffer[i] = int.from_bytes(file.read(1), 'big')
#close file
file.close()
print(" Random Seed: " + chr(file_buffer[-1]))
#set random generator seed
srand(file_buffer[-1])
#decrypt the file
for i in range(3600, file_length, 2):
file_buffer[i] ^= ord(KEY[rand() % KEY_LEN])
#print to check if output is un-encrypted
for i in range(3600, 3613, 1):
print(file_buffer[i])
print(chr(file_buffer[i]))
continue
else:
#Do not try to un-encrypt the python script
print("/!\ Can't decode " + filename)
continue
If anyone can help me figure this out I would be grateful, if possible I would love this to work in python but, from what I can gather, it seems like I will have to learn c++ to get it to work.
rand is not a cryptographic function.
rand's algorithm is not stable between systems compilers or anything else.
If you have no choice, your best bet is to use python-C/C++ interoperability techniques and actually run rand() and srand(). That will suck, but it will suck as much as the original code did.

How to send NRPN messages with pygame midi

I'm writing a program that will read incoming cc messages from a device that can only send cc's and send it to another device as an nrpn message. I know how to send cc messages from pygame but I can't wrap my mind around how to send nrpn's. I looked at the Vriareon code and I don't see anywhere in there were it even accesses midi. Can anyone give an example of how this is done?
Thank you!
NRPN messages are CC messages.
However, NRPN numbers are distinct from CC numbers. The MIDI specification says:
Controller number 6 (Data Entry), in conjunction with Controller numbers 96 (Data Increment), 97 (Data Decrement), 98 (Non-Registered Parameter Number LSB), 99 (Non-Registered Parameter Number MSB), 100 (Registered Parameter Number LSB), and 101 (Registered Parameter Number MSB), extend the number of controllers available via MIDI. Parameter data is transferred by first selecting the parameter number to be edited using controllers 98 and 99 or 100 and 101, and then adjusting the data value for that parameter using controller number 6, 96, or 97.
To change a controller like volume (7), you would send a single message:
B0 07 xx
To change an NRPN, you would select the NRPN first:
B0 63 mm
B0 62 ll
And then change the currently selected NRPN with the data entry controller:
B0 06 mm
B0 26 ll (optional, for 14-bit values)
So setting NRPN 0:1 to value 42 could be done with:
self.midi_out.write_short(0xb0, 0x63, 0)
self.midi_out.write_short(0xb0, 0x62, 1)
self.midi_out.write_short(0xb0, 0x06, 42)

Python 2.7 serial port RS232 data read (2 Byte)

I have this code.
import time
import serial
# configure the serial connections
ser = serial.Serial(
port='/dev/ttyS0',
baudrate=2400,
parity=serial.PARITY_ODD,
stopbits=serial.STOPBITS_TWO,
bytesize=serial.EIGHTBITS
)
ser.open()
ser.isOpen()
print ser.portstr
x=ser.read(1)
print type(x)
while True:
print x
time.sleep(1)
When I run this code I get as out rectangular characters.(I dont know how to describe it - maybe some type of block element???).
So I know that the data which I receive consist of:
bit 0 1 2 3 4 5 6 7
LSB D0 D1 D2 D3 D4 D5 par "0"
MSB D6 D7 D8 D9 D10 D11 par "1"
Whole data are in 2 Byte. In first byte are 8bits ( D0-D5 are data, par following word on odd parity, stop bits two).
My question is how I can receive a read this type of data and how convert it to decimal...
Thanks
Try:
binaryReceived = ser.read(2)
if len(binaryReceived)>=2:
decimalReceived = (binaryReceived[0]&0x1f) | (binaryReceived[1]&0x1f)<<5
print decimalReceived
else:
print "two bytes not received"

How to convert midi files to keypresses (in Python)?

I'm trying to read a MIDI file and then convert each note (midi number) to a simulated keypress on the keyboard (A,f,h,J,t...).
I'm able to read any MIDI file with the python-midi library like this:
pattern = midi.read_midifile("example.mid")
and I can also simulate keypresses with pywin32 like this:
shell = win32com.client.Dispatch("WScript.Shell")
shell.SendKeys(key)
But I have no idea on how to actually convert midi numbers (that are in midi files) to keypresses.
To be more precise I'm trying to convert MIDI numbers to notes and then notes to keypresses according to virtualpiano.net (61-key) so that the program would play that piano by pressing the corresponding button on the keyboard (you can press key assist in settings of the piano to see which key is what button)
Of course I would also have to wait between keypresses but that's easy enough.
Any help is appreciated. (Windows 10 64-bit (32-bit Python 2.7))
If you take a look at the midi module that you are using, you will see that there are some constants that can be used to convert notes to their MIDI number and vice versa.
>>> import midi
>>> midi.C_0 # note C octave 0
0
>>> midi.G_3 # G octave 3
43
>>> midi.Gs_4 # G# octave 4
56
>>> midi.A_8 # A octave 8
105
>>> midi.NOTE_VALUE_MAP_SHARP[0]
C_0
>>> midi.NOTE_VALUE_MAP_SHARP[56]
Gs_4
>>> midi.NOTE_VALUE_MAP_SHARP[105]
A_8
Opening a MIDI file with read_midifile() returns a Pattern object which looks like this (taken from the examples):
>>> midi.read_midifile('example.mid')
midi.Pattern(format=1, resolution=220, tracks=\
[midi.Track(\
[midi.NoteOnEvent(tick=0, channel=0, data=[43, 20]),
midi.NoteOffEvent(tick=100, channel=0, data=[43, 0]),
midi.EndOfTrackEvent(tick=1, data=[])])])
The NoteOnEvent contains timing, MIDI number/pitch and velocity which you can retrieve:
>>> on = midi.NoteOnEvent(tick=0, channel=0, data=[43, 20])
>>> on.pitch
43
>>> midi.NOTE_VALUE_MAP_SHARP[on.pitch]
'G_3'
Now all of that is interesting, but you don't really need to convert the MIDI number to a note, you just need to convert it to the keyboard key for that note as used by http://virtualpiano.net/.
Middle C is equal to MIDI 60 and this note corresponds to the 25th key on the virtualpiano keyboard which is activated by pressing the letter t. The next note, Cs_5, is MIDI 61 which is uppercase T (<shift>-t). From there you can work out the mapping for the MIDI numbers to the supported virtualpiano keys; it's this:
midi_to_vk = (
[None]*36 +
list('1!2#34$5%6^78*9(0qQwWeErtTyYuiIoOpPasSdDfgGhHjJklLzZxcCvVbBnm') +
[None]*31
)
The next problem that you will face is sending the key events. Note that in MIDI multiple notes can be played simultaneously, or can overlap in time. This means that you might need to be able to send more than one key press event at the same time.
I don't think that you can handle the velocity using a computer keyboard. There is also the issue of timing, but you said that that's not a problem for you.
Check this question first. This is general idea on how to simulate keypresses, it may look a lot but it's just a big list of keys. Then to convert midi to keyboard buttons you would create a dictionary mapping between notes and Keyboard buttons.
I understand that what you really need is a way to convert a midi note number to a note in standard notation.
Here are some elements from Wikipedia:
... GM specifies that note number 69 plays A440, which in turn fixes middle C as note number 60 ...
(from MIDI - General MIDI
Converting from midi note number (d) to frequency (f) is given by the following formula: f = 2 (d-69)/12 * 440 Hz
(from MIDI Tuning Standard - Frequency values)
And finally from C (musical note) - Designation by octave
Scientific designation |Octave name | Frequency (Hz) | Other names
C4 | One-lined | 261.626 | Middle C
So C4 is midi note 69, and midi notes are separated with a semitone(*). As you have 12 semitones in one octave, you will get C5 at midi note 81, and the famous A440 (midi note 69) is A4 in scientific notation.
As an example for the table
Midi note | Scientific notation
60 | C4
62 | D4
64 | E4
65 | F4
67 | G4
69 | A4
70 | B4
71 | C5
And you would get F♯4 at midi 66...
(*) it is musically what is called equal temperament. Midi allows for finer pitch definition but it would be far beyond this answer.

Converting assembly instructions BL and B to binary

I am trying to understand how a binary containing binary codes get converted to assembly instruction.
For example here is a example output from objdump for an ARM based application:
00008420 <main>:
8420: e92d4800 push {fp, lr}
8424: e28db004 add fp, sp, #4
8428: e24dd008 sub sp, sp, #8
842c: e59f2054 ldr r2, [pc, #84] ; 8488 <main+0x68>
8430: e24b300c sub r3, fp, #12
8434: e1a00002 mov r0, r2
8438: e1a01003 mov r1, r3
843c: ebffffc6 bl 835c <__isoc99_scanf#plt>
8440: e3a03000 mov r3, #0
8444: e50b3008 str r3, [fp, #-8]
8448: ea000006 b 8468 <main+0x48>
844c: e51b3008 ldr r3, [fp, #-8]
8450: e2833001 add r3, r3, #1
8454: e50b3008 str r3, [fp, #-8]
8458: e59f302c ldr r3, [pc, #44] ; 848c <main+0x6c>
845c: e1a00003 mov r0, r3
8460: e51b1008 ldr r1, [fp, #-8]
8464: ebffffb3 bl 8338 <printf#plt>
8468: e51b300c ldr r3, [fp, #-12]
846c: e51b2008 ldr r2, [fp, #-8]
8470: e1520003 cmp r2, r3
8474: bafffff4 blt 844c <main+0x2c>
8478: e3a03000 mov r3, #0
847c: e1a00003 mov r0, r3
8480: e24bd004 sub sp, fp, #4
8484: e8bd8800 pop {fp, pc}
8488: 00008500 .word 0x00008500
848c: 00008504 .word 0x00008504
as you can see in the offset 8464, the binary code ebffffb3 get converted to bl 8338. I want to understand it.
The explicit reason to do it is because I want to add additional regex for instructions existing in the following python code:
[b"[\x00\x08\x10\x18\x20\x28\x30\x38\x40\x48\x70]{1}\x47", 2, 2], # bx reg
[b"[\x80\x88\x90\x98\xa0\xa8\xb0\xb8\xc0\xc8\xf0]{1}\x47", 2, 2], # blx reg
[b"[\x00-\xff]{1}\xbd", 2, 2] # pop {,pc}
As you can see the regex for an bx instruction in the binary is "\x00\x08\x10\x18\x20\x28\x30\x38\x40\x48\x70]{1}\x47" and for blx it is "\x80\x88\x90\x98\xa0\xa8\xb0\xb8\xc0\xc8\xf0". Now I want to add two more instructions B and BL (these are ARM instructions) but I have no idea how to convert the instruction to the similar binary code.
(The source code coming from ROPGadget in github. )
I am trying to understand how a binary containing binary codes get converted to assembly instruction.
Aside: All traditional CPU hardware uses binary logic using some standard transistor configurations for implementing NOT, NOR, NAND, etc. From these few logic gates, you can implement many more sophisticated device and logic using combinations of the logic elements.
So, all CPUs will extract bit fields (a few bit positions, but not necessarily adjacent) and determine which type of instruction it is. Other bit fields will give parameters to the particular opcode.
In 'C', this convert to some mask and compare operations where you extract the bits to be examined and then see if the bit pattern is equal. The specific implementation for the GNU tools (binutils) is arm-dis.c.
This sourceforge project is one source of information, although there are others (including the arm-dis.c file).
|31..28|27..25| 24|23 .. 0|
+------+------+---+----------+
|cond | 101 | L | offset |
+------+------+---+----------+
The only constant part is the '101'. Your python reg-ex looks like hexadecimal. The leading nibble is a condition which if true the instruction will take; otherwise it is like a no op. There was a never (leading hex 'F') condition in very old ARM CPU documentation; it has been deprecated to extend the instruction set. So the leading nibble (four bits) can be ignored and then look for either '1010b' or 0xa (for the branch) and '1011b' or 0xb (for the bl or branch and link).
For example, arm-dis.c has,
{ARM_FEATURE_CORE_LOW (ARM_EXT_V1),
0x0a000000, 0x0e000000, "b%24'l%c\t%b"},
That said, the b and bl instructions are not that useful for ROP as they do not have register arguments, so you can not alter the control flow. Normally, you would just arrange to have the control flow directly in your ROP gadget instead of trying to get to them through a jump.
The ARM version of b Rn is mov pc, rN; but there are many other rich constructs such as add with shift and using ldr with tables of pointer, etc. Afaik, the ROPGadget was detecting these when I ran it on an ARM glibc.
Quoting from https://www.ic.unicamp.br/~ranido/mc404/arm/arm-instructionset.pdf
Branch instructions contain a signed 2’s complement 24 bit offset.
This is shifted left two bits, sign extended to 32 bits, and added to
the PC. The instruction can therefore specify a branch of +/-
32Mbytes. The branch offset must take account of the prefetch
operation, which causes the PC to be 2 words (8 bytes) ahead of the
current instruction. Branches beyond +/- 32Mbytes must use an offset
or absolute destination which has been previously loaded into a
register. In this case the PC should be manually saved in R14 if a
Branch with Link type operation is required.
So let's look at your branch example
8464: ebffffb3 bl 8338 <printf#plt>
The processor logic takes the 24-bit offset ffffb3 and multiplies it by 4 (that's efficiently coded because of 4-byte alignment). It then adds this offset to the current instruction's Program Counter + 8. This gives the sum:
ffffffb3 * 4
--------
fffffecc +
8464 +
8 +
--------
8338 QED

Categories