15 posts / 0 new
Author
Message

Hi I am looking to read out the value of a complete 8bit port ( A on mega pins 22-29 ) and convert that info to an int value ( 1-256 ) for use as an address.

Unit8_t VAR = PinA  ??

-Peter

`Unit8_t VAR = PinA`

Maybe try:

`uint8_t VAR = PINA;`

Jim

I would rather attempt something great and fail, than attempt nothing and succeed - Fortune Cookie

"The critical shortage here is not stuff, but time." - Johan Ekdahl

"Step N is required before you can do step N+1!" - ka7ehk

"If you want a career with a known path - become an undertaker. Dead people don't sue!" - Kartman

"Why is there a "Highway to Hell" and only a "Stairway to Heaven"? A prediction of the expected traffic load?"  - Lee "theusch"

Speak sweetly. It makes your words easier to digest when at a later date you have to eat them ;-)  - Source Unknown

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB, RSLogix user

Thanks for that.

how might I go about converting that to it's int value? 1-512

I'm looking to use dip switches to set a start address which is used as an offset for the number of addresses each receiver has ( this is an RS 485 (DMX) project )

Thanks again

-Peter

Last Edited: Sat. Apr 25, 2020 - 02:37 PM

Well first off, an 8 bit unsigned integer has 256 possible values >>0 - 255<<.  Not 1 - 256, which would require a 16 bit address.

Upstage wrote:
how might I go about converting that to it's int value without reading it out and adding it up?

I do not follow the question.

If you 'READ' the value on PortA via PINA, into variable 'VAR' its already done for you.

For example, if ALL teh pins on PortA are logic '0' then the value of 'VAR' would be 0x00hex (0 in decimal) when the line of code above is performed.

Likewise if only Bit7 of PortA is logic '1', then the value of 'VAR' would be 0x80hex (128 in decimal) when the line of code is performed.

What other 'conversion' are you referring to?

JIm

I would rather attempt something great and fail, than attempt nothing and succeed - Fortune Cookie

"The critical shortage here is not stuff, but time." - Johan Ekdahl

"Step N is required before you can do step N+1!" - ka7ehk

"If you want a career with a known path - become an undertaker. Dead people don't sue!" - Kartman

"Why is there a "Highway to Hell" and only a "Stairway to Heaven"? A prediction of the expected traffic load?"  - Lee "theusch"

Speak sweetly. It makes your words easier to digest when at a later date you have to eat them ;-)  - Source Unknown

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB, RSLogix user

You edited while I was typing.......

I thought DMX used a 16bit address....

Then your DIP switches will be on TWO ports, not just one.

You then can do a simple OR with a mask to a 16bit variable for the full address: DMXAddress for example.

Another approach is to not bother doing ANYTHING with the High and Low address variables as the AVR USART can only send 8 bit chunks anyway....which the DMX receiver can handle as you will be sending oout your data in a DMX formatted PROTOCOL.

do a search of the forums here, and a direct Google Search of DMX and AVR.  This has come up many times in the past.

JIm

I would rather attempt something great and fail, than attempt nothing and succeed - Fortune Cookie

"The critical shortage here is not stuff, but time." - Johan Ekdahl

"Step N is required before you can do step N+1!" - ka7ehk

"If you want a career with a known path - become an undertaker. Dead people don't sue!" - Kartman

"Why is there a "Highway to Hell" and only a "Stairway to Heaven"? A prediction of the expected traffic load?"  - Lee "theusch"

Speak sweetly. It makes your words easier to digest when at a later date you have to eat them ;-)  - Source Unknown

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB, RSLogix user

Hi yes 9 bits anyway?  1-512  hence DMX512 as the standard. ( the offset is done in math 0-511 + 1? )

the addressing I'm looking to do is on the receiver side. dip switches set the offset start address for each fixture in a chain. so it only receives relevant data. currently the fixtures I'm developing are 12ch each 8bit per channel (0-255)

I am currently just using an int offset in the code to test addressing and it works, so I am looking to replace that static offset value with the address from the dip switches.

-Peter

jgmdesign wrote:

I thought DMX used a 16bit address....

jgmdesign wrote:

Then your DIP switches will be on TWO ports, not just one.

But this still holds true. You have 8 bits on one port and the 9th bit on another. Two reads of the ports, a mask, a shift and an add into the int16_t result.

#1 Hardware Problem? https://www.avrfreaks.net/forum/...

#3 All grounds are not created equal

#4 Have you proved your chip is running at xxMHz?

#5 "If you think you need floating point to solve the problem then you don't understand the problem. If you really do need floating point then you have a problem you do not understand."

So. how is your 9-bit DIP switch wired up? What ports and what pins?

At least one other on here is working on DMX at the moment....

#1 Hardware Problem? https://www.avrfreaks.net/forum/...

#3 All grounds are not created equal

#4 Have you proved your chip is running at xxMHz?

#5 "If you think you need floating point to solve the problem then you don't understand the problem. If you really do need floating point then you have a problem you do not understand."

Last Edited: Sat. Apr 25, 2020 - 03:12 PM

I've got all of port A 0-7 full I haven't added the 9th bit yet though I could use the low bit on port B or C and use it for the 9th? (256)

You have 8 bits on one port and the 9th bit on another. Two reads of the ports, a mask, a shift and an add into the int16_t result.

So read both as unit8_t ? or read them in as unit16_t to begin with?

convert the 2nd one to unit16_t and shift the data

haven't done this before any help or guidance is appreciated.

-Peter

Untested...

```#include <mega328p.h>
#include <stdint.h>

void main(void) {

//assumes bits 0 - 7 are on PC0 - PC7
//assumes bit 8 is on PB4
dmx_addr = ((uint16_t)(PINB & 0b00010000) << 4) + PINC;
}```

#1 Hardware Problem? https://www.avrfreaks.net/forum/...

#3 All grounds are not created equal

#4 Have you proved your chip is running at xxMHz?

#5 "If you think you need floating point to solve the problem then you don't understand the problem. If you really do need floating point then you have a problem you do not understand."

`assumes bits 0 - 7 are on PC0 - PC7`

might be slightly more visually pleasing, since an 8th bit is thereafter being added on the "left" (and not on the "right"):

`assumes bits 7 - 0 are on PC7 - PC0`

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

Thanks guys,

I'm using a mega2560 so adapting to it I was thinking

```#include <stdint.h>
pinMode(22, INPUT_PULLUP); //Port A
pinMode(23, INPUT_PULLUP);
pinMode(24, INPUT_PULLUP);
pinMode(25, INPUT_PULLUP);
pinMode(26, INPUT_PULLUP);
pinMode(27, INPUT_PULLUP);
pinMode(28, INPUT_PULLUP);
pinMode(29, INPUT_PULLUP);

pinMode(37, INPUT_PULLUP); //Port C0

void main(void) {

//assumes bits 0 - 7 are on PA0 -PA7
//assumes bit 8 is on PC0
dmx_addr = ((uint16_t)(PINC & 0b00010000) << 4) + PINA;
}```

I'm not at the project right now, hoping to weed out some issues before I get back to it.

-Peter

You'll need to tweak this...

`PINC & 0b00010000) << 4`

...to suit your actual pins used.

#1 Hardware Problem? https://www.avrfreaks.net/forum/...

#3 All grounds are not created equal

#4 Have you proved your chip is running at xxMHz?

#5 "If you think you need floating point to solve the problem then you don't understand the problem. If you really do need floating point then you have a problem you do not understand."

PinMode() (in Arduino at least) is a callable function. You can't put an invocation outside of the body of a function.

hello good from the beginning forgive my bad english
what you are looking to do is this

// ************* get DMX start address **************
void get_dips (void)
{
#ifdef USE_DIP
uint16_t Temp;

if (! (PINE & (1 << PE1))) {// pin10 enable or disable DMX reception
Temp =
(! (PINC & (1 << PC0)) * 1) +
(! (PINC & (1 << PC1)) * 2) +
(! (PINC & (1 << PC2)) * 4) +
(! (PINC & (1 << PC3)) * 8) +
(! (PINC & (1 << PC4)) * 16) +
(! (PINC & (1 << PC5)) * 32) +
(! (PINC & (1 << PC6)) * 64) +
(! (PINC & (1 << PC7)) * 128) +
(! (PINE & (1 << PE2)) * 256);

if (Temp! = 0)
{

}
else
{
UCSR0B & = ~ (1 << RXCIE0); // disable Receiver if start address = 0
for (Temp = 0; Temp <sizeof (DmxRxField); Temp ++)
{
DmxRxField [Temp] = 0;
}
}
#endif

good to set the correct address in DMX are 9 values ​​that add up
If you pay attention to the example you will see that the nine keys placed in GND
gives a value of 512 which is the maximum allowed by the DMX protocol per universe
pin 10 of the keys for the master or slave function
now if you want to save pins you can use the module tm1637 in arduino plus the addition of buttons
https://www.instructables.com/id...

/ *

This software is based on the TM1637 library.
This software is free to use as long as it is not used for commercial purposes, if you like to use this commercially, please send me an email.
This software is writen by joram de Poel: joramdepoel@gmail.com, mail me if you have any questions.

A library will be released in the future to make using the interface even easier.

latest update: 7-12-2018

* /

#define softwareVersion 0.6

// display setup
#include <TM1637.h> // interface module with display, buttons and status leds
#include <EEPROM.h> // store the DMX adress in EEPROM

#define manual 0 // define mode
#define DMX 1

unsigned int displayUpdateDelay = 200; // update display every 200ms
unsigned long lastDisplayUpdate; // to keep track of refresh rate
byte leds = 0x00; // binairy for 8 leds: b00000111, 0x07 all on

// DMX setup
unsigned int DMX_ch_used = 6; // this prevents you from setting an adres which is out of range. (setting 511 as start adres will make the last adres 517 which does not exist)
bool DMX_addr_has_changed = false; // DMX addr is changed -> store it to EEPROM
unsigned int DMX_addr_store_delay = 2000; // ms to wait before storing the addr
unsigned long last_addr_change = 0; // when was the last DMX addres change?
bool mode = DMX;

// pin definitions
#define CLK 2 // pins definitions for TM1637 and can be changed to other ports
#define DIO 3

TM1637 module (DIO, CLK); // define the module

void setup () {
delay (500); // wait for capacitors to charge and external driver to start

module.clearDisplay (); // clear the display, this is needed when the Arduino is reset without disconnecting the power from the interface module.
delay (1);
module.setupDisplay (true, 7);
delay (1);
module.setDisplayToString ("boot"); // show the text booting

// do the rest of the setup here

// this is the last part of the setup

}

void loop () {

unsigned long lastPacket = 200; // you should update this every time a new DMX package is received

// change the status led for DMX according to the time since the last packet
(lastPacket> 500)? leds & = 0x03: leds | = 0x04; // bitmasks are used to select which leds are on or off depending on the time since the last DMX package. this only affects the DMX status led.

saveDMXAddr (); // save the DMX addr to EEPROM after 2 seconds and show SAVE
}
}

if (millis () - lastDisplayUpdate> displayUpdateDelay) {// only update the display at a fixed rate to reduce CPU load.
updateDisplay (); // update display
readButtons (); // check if any buttons are pressed
lastDisplayUpdate = millis (); // update counter to current time
}

// put your code below this line, when using delays the button read might not always responds and the display will not update!

}

void updateDisplay () {
char screenData [4]; // 4 digits
sprintf (screenData, "A% 03u", DMX_addr); // print like A027, if you prefer the adres as d027 you can change the "A% 03u" to "d% 03u"
module.setDisplayToString (screenData); // convert the data to text
module.setSegments (leds, 4); // turn on or off the status leds. You can connect 8 leds if you like and this code does support it.
}

byte btButtons = module.getButtons (); // you can read out 16 buttons with this code, this code does not allow multi button presses

if (btButtons) // if a button is touched
{
if (btButtons == 0x08) {//// b00001000 first button = menu
; // do something when this button is pressed
}
if (btButtons == 0x04) {// b00000100 second button = up
if (DMX_addr> (512 - DMX_ch_used)) {// only do this when possible, if over the highest one go to 1
}
}
if (btButtons == 0x02) {// b00000010 third button = down
DMX_addr - = 1; // same as up but this time down
if (DMX_addr <1) {// go to the highest possible addr when going below 1
}
DMX_addr_has_changed = true; // and set a flag
}
if (btButtons == 0x01) {// b00000001 fourth button = enter
; // do something you like
}
}
}

// function to store the DMX addres to EEPROM and keep it when the device is turned off
EEPROM.write (0, highByte (DMX_addr)); // 255 is the highest value you can store in one EEPROM addres so we split it
EEPROM.write (1, lowByte (DMX_addr)); // this is the other part
module.setDisplayToString ("SAvE"); // display SAvE on the display, SAVE is not displayed correctly so a lowercase 'V' is used
delay (500);
}

// restore the DMX addres from the EEPROM