STM32 Analog Output - stm32f4discovery

I was making a research about analog output from stm32. STM32F407VG user manual and DAC Manual says that STM32 can give analog output from DAC periphal.
Is that analog output really ANALOG ?

That is the idea of the analogue peripherals to be analogue.
Digital ones have two states - 0 and 1.
Analogue ones can have more than one state. The DAC can have as many states as is the resolution of the DAC data register. If DAC has 12 bits resolution it can have 4096 states.
In the fact is not "fully analogue" output only 4096 states output which we can consider as analogue.

The output of the DAC (digital to analog converter) on an STM32 is "really analog" in the sense that it generates any voltage between 0 and the supply voltage. The two DACs in the STM32F407 are 12-bit DACs, which means they can generate 4096 different voltage levels in that range.
Furthermore, the DAC outputs in the STM32F407 can be buffered, which means they can source or sink some current, making the output "look" no different than the output from a typical analog component such as an op amp.
So even though the signal may be generated by digitally controlled mosfets and resistors, it will behave just like a "real" analog signal.

Related

Why is Binary (machine code) based off Boolean Algebra? What would happen if numbers went from 0-9 instead of 0 or 1?

I'm curious to know if it would be possible to create a computer that uses binary that can go from 0000 up to 9999 by having true and false be 1 and 0, but add numbers 2-9 to get more possibilities for numbers. Is binary code only consisting of 0's and 1's for simplicity? Is it because for some reason computers can only understand True and False?
Binary code starts with 0 (0000) and increases to 1 (0001) to 2 (0010) and 10 (1010). Could is be possible for a computer to recognize 0's and 1's but then go to 2's and other numbers? For example, 0000 = 0, 0001 = 1, 0002 = 2, 0009 = 9 then 0010 = 10, and so on.
If this isn't possible somehow, please explain why and give a general explanation of how computers work because I'm interested and want to learn more. If this isn't used because it's inefficient, please epxlain what makes it inefficient and what makes 0's and 1's more efficient.
Thank you.
I expect that it would be possible to create a computer like this but I searched online and couldn't find out why binary code can't have numbers other than 0's and 1's.
Answer to myself for future reference:
Binary is based on Boolean Algebra because it's a base 2 system, and Decimal is a base 10 system that goes from 0-9 instead of 0 or 1 like Binary which is a base 2 system. Computers easily understand binary because its based off on and off states (0 or 1) with 0 being off and 1 being on. Computers use logic gates which are composed of a multitude of transistors that use boolean logic to store data for the computer. Binary makes hardware convenient for computers. Other number systems are used for other purposes different from Binary's purpose. For example, hexadecimal is used to represent numbers that are large in a more simple way that decimal is able to, take the number one million for example,in decimal, it would be 1000000, in binary it would be 11110100001001000000, and in hexadecimal it would be F4240. This is why the Binary number system is based off boolean alegbra and why computers use binary and not other number systems.
It is based on how the data is stored. Each piece of data stored in your memory can have only two values. Think of your memory as a number of glasses which can either be empty or full. Which means the data is stored as bunch of 1s and 0s. This is the result of moving from analog systems to digital, analog values can be between 0 and 1. In analog systems for example, you can have 0.25 or 0.7. But since computers became digital, the logic became binary.
It will be really beneficial to research the history of computers and learn how they evolved over time, if you are interested in this topic.

Nand2Tetris-Obtaining Register from RAM chips

I've recently completed Chapter 3 of the associated textbook for this course: The Elements of Computing, Second Edition.
While I was able to implement all of the chips described in this chapter, I am still trying to wrap my head around how exactly the RAM chips work. I think I understand them in theory (e.g. a Ram4K chip stores a set of 8 RAM512 chips, which itself is a set of 8 RAM64 chips).
What I am unsure about is actually using the chips. For example, suppose I try to output a single register from RAM16K using this code, given an address:
CHIP RAM16K {
IN in[16], load, address[14];
OUT out[16];
PARTS:
Mux4Way16(a=firstRam, b=secondRam, c=thirdRam, d=fourthRam, sel=address[12..13], out=out);
And(a=load, b=load, out=shouldLoad);
DMux4Way(in=shouldLoad, sel=address[12..13], a=setRamOne, b=setRamTwo, c=setRamThree, d=setRamFour);
RAM4K(in=in, load=setRamOne, address=address[0..11], out=firstRam);
RAM4K(in=in, load=setRamTwo, address=address[0..11], out=secondRam);
RAM4K(in=in, load=setRamThree, address=address[0..11], out=thirdRam);
RAM4K(in=in, load=setRamFour, address=address[0..11], out=fourthRam);
}
How does the above code get the underlying register? If I understand the description of the chip correctly, it is supposed to return a single register. I can see that it outputs a RAM4K based on a series of address bits -- does it also get the base register itself recursively through the chips at the bottom? Why doesn't this code have an error if it's outputting a RAM4K when we expect a register?
It's been a while since I did the course so please excuse any minor errors below.
Each RAM chip (whatever the size) consists of an array of smaller chips. If you are implementing a 16K chip with 4K subchips, then there will be 4 of them.
So you would use 2 bits of the incoming address to select what sub-chip you need to work with, and the remaining 12 bits are sent on to all the sub-chip. It doesn't matter how you divide up the bits, as long as you have a set of 2 and a set of 12.
Specifically, the 2 select bits are used to route the load signal to just one sub-chip (ie: using a DMux4Way), so loads only affect that one sub-chip, and they are also used to pick which of the sub-chips outputs are used (ie: a Mux4Way16).
When I was doing it, I found that the simplest way to do things was always use the least-significant bits as the select bits. So for example, my RAM64 chip used address[0..2] as the select bits, and passed address[3..5] to the RAM8 sub-chips.
The thing that may be confusing you is that in these kinds of circuits, all of the sub-chips are activated. It's just that you use the select bits to decide which sub-chip's output to pass on to the outputs, and also as a filter to decide which sub-chip might perform a load.
As the saying goes, "It's turtles (or ram chips) all the way down."

Determine Issuer of EMV card

What would be the best way to determine the issuer of a contactless EMV card. I am trying to determine if a card was issued by Amex, Visa or Mastercard. Is that information available via a USB EMV reader? I don't need to pull any other information from the card..
I'm assuming that it could be done by some python, or C++ code interacting with the card. I'm looking for a good jumping off point.
You should be able to get this info from the successful response of SELECT. Store the list of RIDs ( AID = RID + PIX ), and do SELECT one by one. On success, it will return status bytes 90 00, otherwise 6A 82( file not found ).
The easiest option would be through SELECT command as mentioned
before. The list of AID:
https://www.eftlab.com/knowledge-base/211-emv-aid-rid-pix/
The other option would be getting it from the PAN. You can define issuer
based on first 6 digits or 8 digits of the PAN, which represents Issuer
Identification Number (IIN)/Bank Identification Number(BIN).
34, 37 - American Express
4 - Visa
51-55, 2221-2720 - MasterCard
https://en.wikipedia.org/wiki/Payment_card_number#Issuer_identification_number_(IIN)
You would have to send commands:
SELECT
GET PROCESSING OPTIONS
READ RECORD
You would look for 5A - PAN and extract first digits.
Good tool that you can just use to read data from contactless EMV card is:
https://www.javacardos.com/tools/pyresman
You can create your own scripts or just proceed with some basic commands like a SELECT command.

Analog to digital module on IAR embedded workbench

I have just started to work on this workbench for stellaris 6965. My task is to convert a 5V analog input to digital and light up an LED.
Please tell me how to do it!
The first thing that needs to be done is to read the analog input and obtain the digital value (which will be memorized into one of the ADC registers).
The value you will receive will range between 0 - 1023 (2^8-1), if you use an 8-bit ADC. The exact register where your value will be memorized depends on the analog pin you have the input voltage.
After that, you can compare the value of the register (I recommend memorizing it into a variable first since it's volatile -> it can change at any moment) and set a threshold for lighting the LED. So, if your value is greater than x (where x is your threshold) you set the digital output pin to 1. Otherwise you set it to zero.
The operations described above can be put into the main program loop or in a timer interrupt.

Compressing a binary matrix

We were asked to find a way to compress a square binary matrix as much as possible, and if possible, to add redundancy bits to check and maybe correct errors.
The redundancy thing is easy to implement in my opinion. The complicated part is compressing the matrix. I thought about using run-length after reshaping the matrix to a vector because there will be more zeros than ones, but I only achieved a 40bits compression (we are working on small sizes) although I thought it'd be better.
Also, after run-length an idea was Huffman coding the matrix, but a dictionary must be sent in order to recover the original information.
I'd like to know what would be the best way to compress a binary matrix?
After reading some comments, yes #Adam you're right, the 14x14 matrix should be compressed in 128bits, so if I only use the coordinates (rows&cols) for each non-zero element, still it would be 160bits (since there are twenty ones). I'm not looking for an exact solution but for a useful idea.
You can only talk about compressing something if you have a distribution and a representation. That's the issue of the dictionary you have to send along: you always need some sort of dictionary of protocol to uncompress something. It just so happens that things like .zip and .mpeg already have those dictionaries/codecs. Even something as simple as Huffman-encoding is an algorithm; on the other side of the communication channel (you can think of compression as communication), the other person already has a bit of code (the dictionary) to perform the Huffman decompression scheme.
Thus you cannot even begin to talk about compressing something without first thinking "what kinds of matrices do I expect to see?", "is the data truly random, or is there order?", and if so "how can I represent the matrices to take advantage of order in the data?".
You cannot compress some matrices without increasing the size of other objects (by at least 1 bit). This is bad news if all matrices are equally probable, and you care equally about them all.
Addenda:
The answer to use sparse matrix machinery is not necessarily the right answer. The matrix could for example be represented in python as [[(r+c)%2 for c in range (cols)] for r in range(rows)] (a checkerboard pattern), and a sparse matrix wouldn't compress it at all, but the Kolmogorov complexity of the matrix is the above program's length.
Well, I know every matrix will have the same number of ones, so this is kind of deterministic. The only think I don't know is where the 1's will be. Also, if I transmit the matrix with a dictionary and there are burst errors, maybe the dictionary gets affected so... wouldnt be the resulting information corrupted? That's why I was trying to use lossless data compression such as run-length, the decoder just doesnt need a dictionary. --original poster
How many 1s does the matrix have as a fraction of its size, and what is its size (NxN -- what is N)?
Furthermore, this is an incorrect assertion and should not be used as a reason to desire run-length encoding (which still requires a program); when you transmit data over a channel, you can always add error-correction to this data. "Data" is just a blob of bits. You can transmit both the data and any required dictionaries over the channel. The error-correcting machinery does not care at all what the bits you transmit are for.
Addendum 2:
There are (14*14) choose 20 possible arrangements, which I assume are randomly chosen. If this number was larger than 128^2 what you're trying to do would be impossible. Fortunately log_2((14*14) choose 20) ~= 90bits < 128bits so it's possible.
The simple solution of writing down 20 numbers like 32,2,67,175,52,...,168 won't work because log_2(14*14)*20 ~= 153bits > 128bits. This would be equivalent to run-length encoding. We want to do something like this but we are on a very strict budget and cannot afford to be "wasteful" with bits.
Because you care about each possibility equally, your "dictionary"/"program" will simulate a giant lookup table. Matlab's sparse matrix implementation may work but is not guaranteed to work and is thus not a correct solution.
If you can create a bijection between the number range [0,2^128) and subsets of size 20, you're good to go. This corresponds to enumerating ways to descend the pyramid in http://en.wikipedia.org/wiki/Binomial_coefficient to the 20th element of row 196. This is the same as enumerating all "k-combinations". See http://en.wikipedia.org/wiki/Combination#Enumerating_k-combinations
Fortunately I know that Mathematica and Sage and other CAS software can apparently generate the "5th" or "12th" or arbitrarily numbered k-subset. Looking through their documentation, we come upon a function called "rank", e.g. http://www.sagemath.org/doc/reference/sage/combinat/subset.html
So then we do some more searching, and come across some arcane Fortran code like http://people.sc.fsu.edu/~jburkardt/m_src/subset/ksub_rank.m and http://people.sc.fsu.edu/~jburkardt/m_src/subset/ksub_unrank.m
We could reverse-engineer it, but it's kind of dense. But now we have enough information to search for k-subset rank unrank, which leads us to http://www.site.uottawa.ca/~lucia/courses/5165-09/GenCombObj.pdf -- see the section
"Generating k-subsets (of an n-set): Lexicographical
Ordering" and the rank and unrank algorithms on the next few pages.
In order to achieve the exact theoretically optimal compression, in the case of a uniformly random distribution of 1s, we must thus use this technique to biject our matrices to our output number of range <2^128. It just so happens that combinations have a natural ordering, known as ranking and unranking of combinations. You assign a number to each combination (ranking), and if you know the number you automatically know the combination (unranking). Googling k-subset rank unrank will probably yield other algorithms.
Thus your solution would look like this:
serialize the matrix into a list
e.g. [[0,0,1][0,1,1][1,0,0]] -> [0,0,1,0,1,1,1,0,0]
take the indices of the 1s:
e.g. [0,0,1,0,1,1,1,0,0] -> [3,5,6,7]
1 2 3 4 5 6 7 8 9 a k=4-subset of an n=9 set
take the rank
e.g. compressed = rank([3,5,6,7], n=9)
compressed==412 (or something, I made that up)
you're done!
e.g. 412 -binary-> 110011100 (at most n=9bits, less than 2^n=2^9=512)
to uncompress, unrank it
I'll get to 128 bits in a sec, first here's how you fit a 14x14 boolean matrix with exactly 20 nonzeros into 136 bits. It's based on the CSC sparse matrix format.
You have an array c with 14 4-bit counters that tell you how many nonzeros are in each column.
You have another array r with 20 4-bit row indices.
56 bits (c) + 80 bits (r) = 136 bits.
Let's squeeze 8 bits out of c:
Instead of 4-bit counters, use 2-bit. c is now 2*14 = 28 bits, but can't support more than 3 nonzeros per column. This leaves us with 128-80-28 = 20 bits. Use that space for array a4c with 5 4-bit elements that "add 4 to an element of c" specified by the 4-bit element. So, if a4c={2,2,10,15, 15} that means c[2] += 4; c[2] += 4 (again); c[10] += 4;.
The "most wasteful" distribution of nonzeros is one where the column count will require an add-4 to support 1 extra nonzero: so 5 columns with 4 nonzeros each. Luckily we have exactly 5 add-4s available.
Total space = 28 bits (c) + 20 bits
(a4c) + 80 bits (r) = 128 bits.
Your input is a perfect candidate for a sparse matrix. You said you're using Matlab, so you already have a good sparse matrix built for you.
spm = sparse(dense_matrix)
Matlab's sparse matrix implementation uses Compressed Sparse Columns, which has memory usage on the order of 2*(# of nonzeros) + (# of columns), which should be pretty good in your case of 20 nonzeros and 14 columns. Storing 20 values sure is better than storing 196...
Also remember that all matrices in Matlab are going to be composed of doubles. Just because your matrix can be stored as a 1-bit boolean doesn't mean Matlab won't stick it into a 64-bit floating point value... If you do need it as a boolean you're going to have to make your own type in C and use .mex files to interface with Matlab.
After thinking about this again, if all your matrices are going to be this small and they're all binary, then just store them as a binary vector (bitmask). Going off your 14x14 example, that requires 196 bits or 25 bytes (plus n, m if your dimensions are not constant). That same vector in Matlab would use 64 bits per element, or 1568 bytes. So storing the matrix as a bitmask takes as much space as 4 elements of the original matrix in Matlab, for a compression ratio of 62x.
Unfortunately I don't know if Matlab supports bitmasks natively or if you have to resort to .mex files. If you do get into C++ you can use STL's vector<bool> which implements a bitmask for you.