How do you watch for changes in the least significant bit? - arduino

I'm working with Arduino and am beginning to work with port registers. I love the speed increases and ability to change multiple ports at the same time. However, I don't know how to watch for a single pin changing using the port registers. (I think it can be done with bitmath, but I don't even know how to start with that.)
So when I check my port register I should get something like this:
PINB = B000xxxxx
Where x are my pin values. Any of those pins could have changed. I want to know when just the rightmost (least significant?) bit has changed. How can I use bitmath to check that just the last one has switched from a 0 to a 1?

"Bitmath" is indeed the answer to the problem. In your case: x & 0x01 will "mask" all but the lowest bit. The result can be compared to 0 or 1 at your wish.
Common idioms are:
x & 0x01 // get only the lowest bit
x & ~0x01 // clear only the lowest bit
x & 0xFE // same: clear only the lowest bit
x | 0x01 // set the lowest bit (others keep their state)

To find out if the bit has changed, you need the previous value, which you mask out as the others have said --
int lastValue = PINB & 0x01;
Then in your code you do
int currentValue = PINB & 0x01;
to get the LSB of the current pin value.
To determine if there was a change to the bit you want the "exclusive OR" (^) operator -- it is "true" if and only if the two bits are different.
if (lastValue ^ currentValue) {
// Code to execute goes here
// Now save "last" as "current" so you can detect the next change
lastValue = currentValue;
}

Related

Adding 0X80 + 0X80

As a preparation for my exam in Microcontrollers, I have this question:
How are the condition bits set when the Byte operation 0x80 + 0x80 is executed?
I understand how to add those 2, but I get 256 and I don't know which condition bits are set in this case.
First, the highest value one byte can hold is 255 (0xFF), so I do not think the result would be 256, but rather, overflow would cause the resulting value to be 0 (0x00).
Secondly, the condition bits would depend on your processor, but going by some ARM notes, I might reasonably expect:
Z: Zero
The Z flag is set if the result of the flag-setting instruction is zero.
C: Carry (or Unsigned Overflow)
The C flag is set if the result of an unsigned operation overflows the 32-bit result register. This bit can be used to implement 64-bit unsigned arithmetic, for example.

How to know if vector is undefined

What I have
I've a signal of std_logic_vector. I need to give it values from a ROM, what I already do.
The problem
At the beginning of the simulation or use, there's an initialization process which makes it to need some time before ROM returns it first value (about 2 clk period).
Until then, ROM output vector is "UUUU" (since it's 4 bits of width). Let's call this signal ROM_coef_inf, so in simulation, this appears with "UUUU" value, so its colour is orange.
I need
I need to know how can I compare this output in order to know if it's an "undefined vector", in order to give another value (i.e. "0000") to my vector until the first ROM value is ready.
There are several possible solutions:
You could initialize all registers between your ROM and your destination (at least in simulation) with a different value to "UUUU".
A standard compare can test for all 9 STD_LOGIC values:
if (mySignal == 'U') then
You can test signals for special values with is_x(...).
Is is defined like this:
FUNCTION Is_X ( s : std_ulogic) RETURN BOOLEAN IS
BEGIN
CASE s IS
WHEN 'U' | 'X' | 'Z' | 'W' | '-' => RETURN TRUE;
WHEN OTHERS => NULL;
END CASE;
RETURN FALSE;
END;
There are overload for vectors, too.
I assume this is for FPGA use, in which case all registers will have a predictable value after programming, which is zeros unless you specify something else. If all you need is for ROM_coef_inf to have zeros instead of U's for the first clock cycles in simulation, you can simply specify an initial value when declaring the signal:
signal ROM_coef_inf : std_logic_vector(3 downto 0) := "0000";
In ASICs registers will have an unknown value after power is applied. In this case you need to use a reset signal to clear all the registers in your design. It is often a good idea to use a reset signal in an FPGA as well, for example to prevent your circuit from doing anything until the clock is stable.
The answer provided by #Paebbels works only in simulation. In the real world the signals tend to be either an 1 or a 0 (or a transition between them, but that is not discussed here). Number 1 will work, but you need to set it to a value that will never occur in your ROM if you want to check for uninitialized. The simpler option is to count clock cycles. The ROM will always behave the same. So if it takes three cycles to get the first data out, it will always take three cycles. So if you count three cycles you are ok.

Change bit state in Julia

In Julia language how can one set, clear and reverse a single bit? I hope you won't consider this question out of scope or too broad; if so, please comment it instead of downvote it.
Having this paragraph from Julia-Lang doc:
Currently, only sizes that are multiples of 8 bits are supported.
Therefore, boolean values, although they really need just a single
bit, cannot be declared to be any smaller than eight bits.
First it's possible to take a look at the binary representation of a variable like this:
julia> bits(Int(10))
"00000000000000000000000000001010"
and secondly, one can create byte value directly using its binary form:
julia> val=0b100
0x04
julia> typeof(val)
UInt8
and lastly, the best way to change value of a bit is performing right binary operation on its byte value:
julia> val | 0b10 # set 2nd bit
0x06
julia> bits(ans)
"00000110"
julia> val & 0b11111011 # clear 3nd bit
0x00
I assume you are wanting to clear, set and check the states of specific bits in a byte.
Where:
N represents the integer in question and;
n is the number of the bit in question (i.e: the n-th bit) and;
the LSB is 1-th bit
set the n-th bit: N |= 2^(n-1)
clear the n-th bit: N &= ~(2^(n-1))
check the state of a bit by copying and shifting: (N >> (n-1)) & 1 != 0
check the state of a bit using a bit-mask: mask = 2^(n-1); N & mask != mask
reverse/toggle/invert the n-th bit, using XOR: N ⊻= 2^(n-1). The xor function may also be used.

Arduino - create dynamic rules

I want to create a program for arduino in order to be able to add and remove rules controlling some pins, whenever i want and not hardcode them.
For example a rule like this:
if pin1=HIGH and pin2=LOW then pin3=HIGH
i want to turn into this:
if(pin1 == HIGH && pin2 == LOW){
digitalWrite(pin3, HIGH);
}
Lets say we pass the rule via the command line as a string.
How could i convert this string into a rule? Is something like this possible?
Your second piece of code:
if(pin1 == HIGH && pin2 == LOW){
digitalWrite(pin3, HIGH);
}
is compiled by your IDE into machine code. That machinecode is then uploaded to the Arduino and then executed.
Therefore you cannot just send some string like this
if pin1=HIGH and pin2=LOW then pin3=HIGH
to the Arduino because after your programm transformed that into the desired form the complete IDE and compiler stuff is missing on the Arduino side. And a C++ compiler tool chain is big - several tens of megabytes! There is no place for that on the Arduino.
What you can do: Invent a simple language for your rules and develop an interpreter for that which then runs on the Arduino.
Perhaps you also don't need to reinvent the wheel - Google for simple BASIC interpreters running on the AVR CPUs and adapt one of them.
What you are asking for is possible but with much work on your part.
Approach 1 (think big):
What you are looking for is a software implementation equivelant to how PAL's (programmable array logic) and CPLD's (complex programmable logic device) operate. If you read this article, you will get some ideas on how this is done in hardware:
Wikipedia article on PLD's
A PAL can create arbitray combinational logic rules between a set of inputs and outputs, i.e. anything you can express as a logical equation of AND's, OR's and NOT's can be programmed. It is programmed by "burning" a set of fuses that connect the inputs to logics gates and then to outputs. What is uploaded to these devices is just a set of 0's and 1's.
You could implement such a thing in software with an array of 0's and 1's to represent the fuses. The hard code would run over the array and calculate the output. You would need to develop the method to load the array with the correct fuses.
A common method by which PAL's are programmed is with the language VHDL. The compiler for this language takes an expression like yours and translates it to the set of AND's, OR's and NOT's that the PAL can use. A search will yield endless discussion of this language, for example:
A VHDL tutorial
You would have to create the compiler that takes the text input and determines the fuses. You would be undertaking some significant tasks:
a domain specific language parser (I can recommend ANTLR),
a PAL compiler (I can't recommend anyone do this themselves), and
the Arduino code to emulate a PAL.
By the time you create your own equivalent of VHDL and PAL's, you'll probably be thinking you could have just put a PAL chip on a proto board and been done.
Approach 2 (more practical):
The simpler method to achieve the same result is a truth table. A truth table is the equivalent of some set of logical expressions. To implement a truth table, translate your logic expressions to a table with one row for each input case. Here is an example of a truth table of two inputs that drive an output:
IN1 IN2 OUT
0 0 1
0 1 0
1 0 1
1 1 1
The code for such a truth table implementation looks like this:
const int IN1 = 6;
const int IN2 = 7;
const int OUTA = 13;
byte table[4] = {1, 0, 1, 1};
void loop() {
int in1;
int in2;
byte outbit;
size_t ix;
//
in1 = digitalRead(IN1);
in2 = digitalRead(IN2);
ix = in2 * 2 + in1;
outbit = table[ix];
digitalWrite(OUTA, outbit);
}
The complete expression of the logic rules is the array of 4 bytes. To "program" an new output equation, you just send a new set of 4 values, for your specific equation you send "0 0 1 0". Your program would receive the list of values and store them in the table array. As soon as the new values/rules are stored, the function of the output would change.
This type of programmable logic is feasible as long as you have enough RAM to store the table. For 4 inputs you just need 16 values, for 5 you need only 32.
Your question raises a keen point in electronics design: you need to pick the right device for the right problem. Code is not always better or easier. Avoid the hammer-nail trap (when your only tool is a hammer every problem looks like a nail). A PAL/CPLD and microcontroller are a powerful combination.
To add to the truth table approach mentioned by #jdr5ca, it's a good idea to understand the controller used in the arduino as well as using the ardiuno libraries.
Pins 0 to 7 are port D and pins 8 to 15 port B. Each port is represented as three single byte registers - PORT_ which is output/bias resistor, PIN_ which is input state and DDR_ which is direction. When you call digitalRead(pin) the code sees which range the pin is in, reads PIN_ for that port, then bit-shifts and masks the value to give just that pin's state. Which is handy for reading one pin at a time, but a less convenient than if you're reading several.
So if you create a truth table with 256 entries, you can write the output of pins 8 to 15 from the values of inputs 0 to 7 using a single line, rather than decoding the registers to pins then encoding them again:
byte table[256] = {0};
void loop() {
PORTB = table[PIND];
}
You can then add something to read from the serial and load new values into the table on the fly.

Is there any sense in performing binary AND with a number where all bits are set to 1

Greetings everybody. I have seen examples of such operations for so many times that I begin to think that I am getting something wrong with binary arithmetic. Is there any sense to perform the following:
byte value = someAnotherByteValue & 0xFF;
I don't really understand this, because it does not change anything anyway. Thanks for help.
P.S.
I was trying to search for information both elsewhere and here, but unsuccessfully.
EDIT:
Well, off course i assume that someAnotherByteValue is 8 bits long, the problem is that i don't get why so many people ( i mean professionals ) use such things in their code. For example in SharpZlib there is:
buffer_ |= (uint)((window_[windowStart_++] & 0xff |
(window_[windowStart_++] & 0xff) << 8) << bitsInBuffer_);
where window_ is a byte buffer.
The most likely reason is to make the code more self-documenting. In your particular example, it is not the size of someAnotherByteValue that matters, but rather the fact that value is a byte. This makes the & redundant in every language I am aware of. But, to give an example of where it would be needed, if this were Java and someAnotherByteValue was a byte, then the line int value = someAnotherByteValue; could give a completely different result than int value = someAnotherByteValue & 0xff. This is because Java's long, int, short, and byte types are signed, and the rules for conversion and sign extension have to be accounted for.
If you always use the idiom value = someAnotherByteValue & 0xFF then, no matter what the types of the variable are, you know that value is receiving the low 8 bits of someAnotherByteValue.
uint s1 = (uint)(initial & 0xffff);
There is a point to this because uint is 32 bits, while 0xffff is 16 bits. The line selects the 16 least significant bits from initial.
Nope.. There is no use in doing this. Should you be using a value that is having its importance more than 8 bits, then the above statement has some meaning. Otherwise, its the same as the input.
If sizeof(someAnotherByteValue) is more than 8 bits and you want to extract the least signficant 8 bits from someAnotherByteValue then it makes sense. Otherwise, there is no use.
No, there is no point so long as you are dealing with a byte. If value was a long then the lower 8 bits would be the lower 8 bits of someAnotherByteValue and the rest would be zero.
In a language like C++ where operators can be overloaded, it's possible but unlikely that the & operator has been overloaded. That would be pretty unusual and bad practice though.
EDIT: Well, off course i assume that
someAnotherByteValue is 8 bits long,
the problem is that i don't get why so
many people ( i mean professionals )
use such things in their code. For
example in Jon Skeet's MiscUtil there
is:
uint s1 = (uint)(initial & 0xffff);
where initial is int.
In this particular case, the author might be trying to convert an int to a uint. The & with 0xffff would ensure that it would still convert Lowest 2 Bytes, even if the system is not one which has a 2 byte int type.
To be picky, there is no guaranty regarding a machine's byte size. There is no reason to assume in a extremely portable program that the architecture byte is 8 bits wide. To the best of my memory, according to the C standard (for example), a char is one byte, short is wider or the same as char, int is wider or the same as short, long is wider or the same as int and so on. Hence, theoretically there can be a compiler where a long is actually one byte wide, and that byte will be, say, 10 bits wide. Now, to ensure your program behaves the same on that machine, you need to use that (seemingly redundant) coding style.
"Byte" # Wikipedia gives examples for such peculiar architectures.

Resources