Nibble advice needed!

chigley

Senior Member
Hey all,

Currently working on a new project - an electronic version of the board game Mastermind (the one with the different coloured pegs, the combination of which has to be guessed in the lowest number of tries possible.)

Going well so far, and I'm coping well with controlling such a vast amount of RGB LEDs! I am, however, having one problem which I'm going to try my best to describe as simply as possible.

In order to be able to produce 6 different colours for the LED 'pegs', the LED controllers (3xMAX6956, one for red, one for green, one for blue) can individually control the current sink of a cathode in steps of 1/16th. This is great, except the controllers use one byte to control the current level of two LED ports.

For example, at address $16 the first nibble of the byte (4 bits, 7-4) controls current for port 13, and the second nibble (3-0) controls the current for port 12.

I'm building a subroutine which takes in the port ID and colour ID of a given RGB LED and adjusts the I/O state and current level of all three LED elements within the RGB LED to achieve the colour. The I/O states are easy; the problem I'm having is with changing just 4 bits of the existing current value to work out the new one to send to the controller (I2C).

I know the existing current byte of each colour element. I know the new state of one of the nibbles, and I also know whether or not this is to be the first or second four bits.

For example,

Code:
Current current value: %10101111
New current value: %11100000 (last 4 bits are 0s given that they should be ignored anyway)
Mask (based on whether port number is even or odd): %11110000
The code needs to calculate the new current value to be sent to the controller as %11101111. It should choose the first nibble from the new value, and the second nibble from the existing value, and combine the two together. If the mask were the other way round (i.e. %00001111) then the new current byte should be %10100000 based on the above data.

I'm assuming this is possible? I'm guessing with bitwise operators but I can't think of a way how. I also tried manually setting the bits but this of course isn't possible beyond bit15 of my PICAXE 18X.

Any suggestions much appreciated. Hope I've explained it well enough!

Thanks as always,

Charlie
 

Chavaquiah

Senior Member
Your idea of using bitwise operators is a good one.

When you AND two bytes (say %10101010 and %11110000), only corresponding bits that are 1 in both bytes will remain 1, all others will go to zero. In the previous example, the result would be 10100000.

With OR (|), if any (one or both) of the corresponding bits is 1, the resulting bit will be 1: %10101010 OR %11110000 = %11111010.

So, you could do something along the following lines:
Code:
#picaxe 18X

symbol CurrentValue = b0
symbol NewNibble = b1 'Use only 4 MSB (bit7-bit4)
symbol LEDPort = b2
symbol NewValue = b3
symbol IsOdd = b4


main:
	CurrentValue = %10101111
	NewNibble = %11100000
	LEDPort = 2
	gosub CalcNewVal
	debug
	pause 10000
	end


CalcNewVal:
	IsOdd = LEDPort % 2 'Result = 1 for odd numbers, 0 for even numbers
	if IsOdd = 1 then 'Odd Port
                NewNibble = NewNibble & %11110000 'Make sure LSB are zero
		NewValue = CurrentValue & %00001111 | NewNibble
	else
		NewNibble = NewNibble / 16 'Shift 4 bits to right
		NewValue = CurrentValue & %11110000 | NewNibble
	endif
	return
Not very efficient code, but I hope it shows what's going on.
 

lanternfish

Senior Member
Current current value: %10101111
New current value: %11100000 (last 4 bits are 0s given that they should be ignored anyway)
Mask (based on whether port number is even or odd): %11110000
Or you could try:

High Nibble:
Current current value AND %00001111 + New current Value

eg %10101111 AND %00001111 + %11100000

Low Nibble:
New current value = New current value / 16 ;This shifts high nibble to low nibble
current value = Current current value AND %11110000 + New current Value

?y keyboqrd hqs gone qll loopy: Bqck soon1
 

chigley

Senior Member
Thanks to both of you, especially Chavaquiah!
Your code worked first time, and I understand it too :)

Charlie
 
Top