Show Posts
Pages: [1] 2 3
1  Using Arduino / Programming Questions / Accessing array elements inside structs on: June 01, 2014, 03:08:10 pm
Hi,

I hope someone more familiar with C can give me some guidance.

I'm writing a program which will read a number of temperature "probes". Each probe consists of upto twelve DS18B20 temperature sensors to be accessed over OneWire bus. There may be up to 32 Probes in the whole system. Hence, maximal possible number of sensors is 12 per probe * 32 probes = 384 sensors. Each sensor requires a hard coded 8 byte address, hence 384*8 bytes = 3072 bytes of data just for storing the addresses.

I have tried a few different implementations in order to use flash (PROGMEM) for storing these addresses, but they seem to always eat into SRAM (accroding to avr-size) and hence I quickly run out of SRAM with all the other code running. Ultimately this will go into an Arduino Mega2560.

Finally, I am trying yet another implementation which I hope will work. I have stripped the example to the bare minimum needed to present here.

Namely, there are const uint8_t[8] arrays that hold each address, then these arrays are put into Probe structures (which include some other volatile and non-volatile variables), and finally all Probe structs are collected into a Probes array. This organisation will ultimately allow me to for-loop through all the probes and sensors efficiently, but I first need to get the data organisation working.

The stripped down code is presented below:
Code:
#include <avr/pgmspace.h>
#define PROBES_NUM 2
#define PROBES_MAX 2

// PROBE 00
const prog_uint8_t PROGMEM S00N00[8] = {0x28, 0x92, 0x2C, 0xB9, 0x05, 0x00, 0x00, 0x2F}; // LEVEL 00
const prog_uint8_t PROGMEM S00N01[8] = {0x28, 0x47, 0x4D, 0xB9, 0x05, 0x00, 0x00, 0xDC}; // LEVEL 01
const prog_uint8_t PROGMEM S00N02[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; // LEVEL 02
const prog_uint8_t PROGMEM S00N03[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; // LEVEL 03
const prog_uint8_t PROGMEM S00N04[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; // LEVEL 04
const prog_uint8_t PROGMEM S00N05[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; // LEVEL 05
const prog_uint8_t PROGMEM S00N06[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; // LEVEL 06
const prog_uint8_t PROGMEM S00N07[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; // LEVEL 07
const prog_uint8_t PROGMEM S00N08[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; // LEVEL 08
const prog_uint8_t PROGMEM S00N09[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; // LEVEL 09
const prog_uint8_t PROGMEM S00N10[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; // LEVEL 10
const prog_uint8_t PROGMEM S00N11[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; // LEVEL 11

// PROBE 01
const prog_uint8_t PROGMEM S01N00[8] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; // LEVEL 00
const prog_uint8_t PROGMEM S01N01[8] = {0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB}; // LEVEL 01
const prog_uint8_t PROGMEM S01N02[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; // LEVEL 02
const prog_uint8_t PROGMEM S01N03[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; // LEVEL 03
const prog_uint8_t PROGMEM S01N04[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; // LEVEL 04
const prog_uint8_t PROGMEM S01N05[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; // LEVEL 05
const prog_uint8_t PROGMEM S01N06[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; // LEVEL 06
const prog_uint8_t PROGMEM S01N07[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; // LEVEL 07
const prog_uint8_t PROGMEM S01N08[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; // LEVEL 08
const prog_uint8_t PROGMEM S01N09[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; // LEVEL 09
const prog_uint8_t PROGMEM S01N10[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; // LEVEL 10
const prog_uint8_t PROGMEM S01N11[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; // LEVEL 11

typedef struct {
const char PROGMEM name[9];
const int PROGMEM numLevels;
const prog_uint8_t *levels[12];
float temperatures[12];
OneWire *line;
} PROGMEM Probe;

// PROBE 00
Probe PROGMEM Probe00Struct = {
"TestS00",                                        // Name of Probe (Max 8 chars)
2,                                                // Num of levels
S00N00,                                           // Level 1
S00N01,                                           // Level 2
S00N02,                                           // Level 3
S00N03,                                           // Level 4
S00N04,                                           // Level 5
S00N05,                                           // Level 6
S00N06,                                           // Level 7
S00N07,                                           // Level 8
S00N08,                                           // Level 9
S00N09,                                           // Level 10
S00N10,                                           // Level 11
S00N11,                                           // Level 12
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,               // Temperatures
0                                                 // OneWire Line
};

// PROBE 01
Probe PROGMEM Probe01Struct = {
"TestS00",                                        // Name of Probe (Max 8 karaktera)
2,                                                // Num of levles
S01N00,                                           // Level 1
S01N01,                                           // Level 2
S01N02,                                           // Level 3
S01N03,                                           // Level 4
S01N04,                                           // Level 5
S01N05,                                           // Level 6
S01N06,                                           // Level 7
S01N07,                                           // Level 8
S01N08,                                           // Level 9
S01N09,                                           // Level 10
S01N10,                                           // Level 11
S01N11,                                           // Level 12
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,               // Temperatures
0                                                 // OneWire Line
};

and the main file is:

Code:
#include <OneWire.h>
#include "DataStructs.h"


// Instantiation of OneWire protocol
OneWire S0(10); //Pin 10
OneWire S1(11); //Pin 11

Probe *probes[PROBES_NUM] = {&Probe00Struct, &Probe01Struct};

void printAddress(const prog_uint8_t* addr)
{
 int i;
 for (i = 0; i < 8; i++) {
   if (addr[i] < 16) Serial.print("0");
   Serial.print(addr[i], HEX);
   Serial.print(" ");
 }
 Serial.println();
}

void setup(void)
{
  Serial.begin(9600);
 
  Serial.println("Print some info");
  // Assign OneWire instances to Probe Structs
  probes[0]->line = &S0;
  Serial.print("Name of Probe: ");
  Serial.println(probes[0]->name);
  Serial.print("Number of Levels: ");
  Serial.println(probes[0]->numLevels);
 
  printAddress(probes[0]->levels[0]);
 
  // Try accessing OneWire object inside a probe
  probes[0]->line->reset(); // DOES NOT WORK BUT COMPILES
}


void loop(void)
{

}

The code compiles, but running the code I get random gibberish and not what I expect. For instance, I get the following:

Code:
Print some info
Name of Probe:
Number of Levels: 514
05 01 01 02 00 00 00 00

While I would expect:

Code:
Print some info
Name of Probe: TestS00
Number of Levels: 2
28 92 2C B9 05 00 00 0x2F

I'm pretty sure I am not accessing the structures correctly or perhaps I have built a structure different than what I think it should be. I would greatly appreciate if someone could give me some pointers and perhaps note whether this will actually keep all the addresses in Flash and keep them out of SRAM?

Thanks in advance!
2  Using Arduino / Motors, Mechanics, and Power / Re: Identifying type of AC motor on: February 13, 2011, 05:54:29 pm
If it's singly fed, its most likely an induction motor. If it is doubly fed (highly unlikely), it's a synchronous motor.

HTH
-Igor
3  Using Arduino / Motors, Mechanics, and Power / Re: controling Brushless three phase dc motors on: February 11, 2011, 02:32:15 am
retrolefty: I'm pretty sure it's PWM controlled. I varied the on time versus off time to control the speed and direction.

vinceherman: Its exactly how you said it: 1500 zero throttle, 2000 full throttle, and 1000 full reverse.

If anyone is interested let me know and I can try and dig out the VHDL code I developed for driving the ESC. (It's been a while tho, but I'm sure I still have it backed up somewhere)

HTH,
-Igor
4  Using Arduino / Motors, Mechanics, and Power / Re: controling Brushless three phase dc motors on: February 10, 2011, 07:28:07 pm
Hi,

I think its just easier paying for a complete ESC rather than making your own. (Unless, of course, you're doing it for educational reasons.). I used a Turnigy 60A ESCs for a QuadRotor UAV and it worked great and it can be reversed.
Link: http://www.hobbyking.com/hobbyking/store/uh_viewItem.asp?idProduct=7188
It is expensive and probably overkill at 60A, so you might have to search for something with lower current rating and thus cheaper. The ESC takes PWM input as control signal so Arduino should be able to control it. (I used an FPGA for controlling it).

HTH
-Igor
5  Using Arduino / General Electronics / Re: Conductivity of hot glue. on: February 10, 2011, 07:19:45 pm
I've used hot glue guns to coat and isolate a lot of electronic boards. Never had a problem with it starting to conduct, but it may melt if electronics get really hot. So, it always worked for me, but this is just my experience.
-Igor

P.S. It's also great for strengthening connectors and making sure wires will not pull out of headers.
6  Using Arduino / General Electronics / Re: Arduino serial communication pc - MAX 232 on: February 10, 2011, 06:57:10 pm
Just keep in mind, if you're using the PC serial port to talk to the arduino, it WILL kill the arduino. To elaborate:
The serial port on the pc (DB9 connector) uses the standard RS232 voltage levels which are +12v (0) and -12V (1) (Yeah, logic is inverted in reference to voltage levels by the RS232 standard). These voltages will kill the arduino is connected directly. In this case a MAX232 level shifter is required.

As Grumpy_mike noted, if you're just going to talk with the arduino via USB serial link, this link uses TTL levels (+5v and -5V which are NOT the voltage levels specified by the RS232 standard), this will work fine.

In a nutshell: Using serial cable between arduino and PC - need MAX232
Using USB serial link: connect direclty, you're sweet - this link is used to upload programs to the arduino.

HTH
-Igor
7  Using Arduino / General Electronics / Re: Voltage reference on: February 10, 2011, 06:43:23 pm
Hi Eduardo,

I think what you need is a voltage reference IC. Voltage references are like voltage regulators, with the difference that they are very precise (+-0.1%) and can not source much current. They are used exactly as what their name implies - voltage references. One such device, 3.0 V voltage reference is the ADR3430 from Analog Devices. (http://au.element14.com/analog-devices/adr3430arjz/ic-volt-ref-3v-6sot23/dp/1843662).

Hope that helps,
-Igor
8  Using Arduino / Programming Questions / Re: Incrementation bug? WTF? [BROKEN COMPILER - SOLVED] on: February 05, 2011, 12:59:48 am
Awesome!

I pacman -Udf'ed binutils-avr and the blink sketch works fine now (at least on the Uno)! So, no need for gcc-avr (Arch package works fine), we just need these binutils-avr!

Thanks heaps to everyone who spent time to look into these problems. I'll send a message to the Arch User Repository for the arduino package (the package for x86_64).

-Igor
9  Using Arduino / Programming Questions / Re: Incrementation bug? WTF? [BROKEN COMPILER - SOLVED] on: February 04, 2011, 02:32:36 am
I tried the x86_64 packages. Binutils compiled fine, but gcc-avr spit the following error:

Code:
checking for suffix of object files... configure: error: cannot compute suffix of object files: cannot compile
See `config.log' for more details.
make[1]: *** [configure-target-libgcc] Error 1
make[1]: Leaving directory `/home/igor/Misc/ArchBuilds/gcc-avr-debian/src/gcc-4.3.5/build'
make: *** [all] Error 2
    Aborting...
┌─[igor]──[X201]
└─[~/Misc/ArchBuilds/gcc-avr-debian]$

I haven't come across this kind of error before (not really a programmer), but if someone knows what this means, please share!

Thanks for preparing the PKGBUILDS dsh1!
-Igor
10  Using Arduino / General Electronics / Re: Voltage divider: Separate GND on: February 03, 2011, 04:00:18 am
Hi,

I have used a hall effect transducer for a similar application with great success. I used the following component:
http://au.element14.com/allegro-microsystems/acs756sca-050b-pff-t/ic-current-sensor-50a-3ca/dp/1791390&PRED=True&trackKey=VNC_HMP_MID

Very easy to setup, so I highly reccomend it. (The link is for a 50A sensor, if you need to measure smaller currents, it would be better to find a sensor with a lower current rating)

HTH
-Igor
11  Using Arduino / Installation & Troubleshooting / Re: Arduino Mega 1280 delay() turbocharged on: February 03, 2011, 03:23:02 am
Hi,

Here is my dissassmebled code as requested:

Code:
000002fc <delay>:

void delay(unsigned long ms)
{
 2fc:   ef 92           push    r14
 2fe:   ff 92           push    r15
 300:   0f 93           push    r16
 302:   1f 93           push    r17
 304:   cf 93           push    r28
 306:   df 93           push    r29
 308:   7b 01           movw    r14, r22
 30a:   8c 01           movw    r16, r24
        uint16_t start = (uint16_t)micros();
 30c:   0e 94 58 01     call    0x2b0   ; 0x2b0 <micros>
 310:   eb 01           movw    r28, r22

        while (ms > 0) {
 312:   0f c0           rjmp    .+30            ; 0x332 <delay+0x36>
                if (((uint16_t)micros() - start) >= 1000) {
 314:   0e 94 58 01     call    0x2b0   ; 0x2b0 <micros>
 318:   6c 1b           sub     r22, r28
 31a:   7d 0b           sbc     r23, r29
 31c:   83 e0           ldi     r24, 0x03       ; 3
 31e:   68 3e           cpi     r22, 0xE8       ; 232
 320:   78 07           cpc     r23, r24
 322:   38 f0           brcs    .+14            ; 0x332 <delay+0x36>
                        ms--;
 324:   08 94           sec
 326:   e1 08           sbc     r14, r1
 328:   f1 08           sbc     r15, r1
 32a:   01 09           sbc     r16, r1
 32c:   11 09           sbc     r17, r1
                        start += 1000;
 32e:   c8 51           subi    r28, 0x18       ; 24
 330:   dc 4f           sbci    r29, 0xFC       ; 252

void delay(unsigned long ms)
{
        uint16_t start = (uint16_t)micros();

        while (ms > 0) {
 332:   e1 14           cp      r14, r1
 334:   f1 04           cpc     r15, r1
 336:   01 05           cpc     r16, r1
 338:   11 05           cpc     r17, r1
 33a:   61 f7           brne    .-40            ; 0x314 <delay+0x18>
                if (((uint16_t)micros() - start) >= 1000) {
                        ms--;
                        start += 1000;
                }
        }
}
 33c:   df 91           pop     r29
 33e:   cf 91           pop     r28
 340:   1f 91           pop     r17
 342:   0f 91           pop     r16
 344:   ff 90           pop     r15
 346:   ef 90           pop     r14
 348:   08 95           ret

0000034a <init>:


Thanks heaps for looking into this stimmer! Helping others like you have is certainly good karma! smiley-wink

Cheers,
-Igor
12  Using Arduino / Installation & Troubleshooting / Re: Arduino Mega 1280 delay() turbocharged on: February 02, 2011, 04:21:45 am
Hi stimmer,

None of those environment variables seem to be set:

Code:
┌─[igor]──[X201]
└─[~]$ echo $PATH
/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin:/opt/java/bin:/opt/java/db/bin:/opt/java/jre/bin:/usr/bin/core_perl:/usr/local/bin:/usr/local/bin
┌─[igor]──[X201]
└─[~]$ echo $CFLAGS

┌─[igor]──[X201]
└─[~]$ echo $C_INCLUDE_PATH

┌─[igor]──[X201]
└─[~]$ echo $C_PLUS_INCLUDE_PATH

┌─[igor]──[X201]
└─[~]$ echo $LIBRARY_PATH

┌─[igor]──[X201]
└─[~]$

I'll dive into the issue in more detail as soon as I get some free time. I just updated Arch linux and saw it pulled a new gcc in, so I will recompile the sketches and see if anything changes. If I can't figure anything out, I'll get in touch with the Arch linux arduino package maintainer and let him know about this issue, since it seems to be Arch specific.

Cheers,
-Igor
13  Using Arduino / Installation & Troubleshooting / Re: Arduino Mega 1280 delay() turbocharged on: January 28, 2011, 11:29:26 pm
Thanks for that.
I'll try to downgrade my avr-gcc but its not a trivial matter on Arch linux (rolling release model).
-Igor
14  Using Arduino / General Electronics / Re: divider/counter chip on: January 28, 2011, 09:54:59 pm
FPGA's are the future. I used a Digilent Nexys quite a bit:
http://www.digilentinc.com/Products/Detail.cfm?NavPath=2,400,789&Prod=NEXYS2

-Igor
15  Using Arduino / Installation & Troubleshooting / Re: Arduino Mega 1280 delay() turbocharged on: January 28, 2011, 09:45:42 pm
Thanks for the help guys!

dafid: In fact you're right. I looked at wiring.c a couple of days ago and for some reason I remembered it using delayMicroseconds(), but I just checked again and the implementation of delay() is identical in my wiring.c as what you posted above. It does indeed use micros() - my mistake!

stimmer: I'm running 64 bit Arch Linux and Arduino 0021. The IDE installation on Arch is a bit of a mess since it bundles its own patched avrdude and librxtx with it instead of using the system wide ones. Also, the installation requires removing 64 bit gcc and gcc-libs and installing 64 and 32 bit compatible versions of these packages (gcc-multilib), which is pretty hackish IMHO. In addition, the package is not available from official "repository" but it is user contributed, so it is very likely to be an installation problem. I have removed everything and reinstalled again but the results are the same.

compiler and other program versions are:
Code:
┌─[igor]──[X201]
└─[/usr/share/arduino/hardware/arduino/cores/arduino]$ avr-gcc -v
Using built-in specs.
COLLECT_GCC=avr-gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/avr/4.5.2/lto-wrapper
Target: avr
Configured with: ../configure --disable-libssp --disable-nls --enable-languages=c,c++ --infodir=/usr/share/info --libdir=/usr/lib --libexecdir=/usr/lib --mandir=/usr/share/man --prefix=/usr --target=avr --with-gnu-as --with-gnu-ld --with-as=/usr/bin/avr-as --with-ld=/usr/bin/avr-ld
Thread model: single
gcc version 4.5.2 (GCC)

Code:
┌─[igor]──[X201]
└─[/usr/share/arduino/hardware/arduino]$ avrdude -v

avrdude: Version 5.10, compiled on Nov 29 2010 at 11:24:36

Can you please let me know your avr-gcc compiler version?

Thanks!
-Igor
Pages: [1] 2 3