Pages: 1 [2]   Go Down
Author Topic: [Solved, Thanks] Buggy Circuit - Please help me identify possible causes  (Read 1508 times)
0 Members and 1 Guest are viewing this topic.
Southern Ontario
Offline Offline
Sr. Member
****
Karma: 2
Posts: 279
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

One thing that would make a big difference is getting rid of the matrix for a for loop.  If you look at the data in the array you'll notice that the binary value (reading from left to right: 1 , 2, 4, 8) of the mux select pins is equal to the pin it selects:
Code:
{1,0,0,0}, //SparkFun Input # 1  = 0001
{1,0,1,0}, //SparkFun Input # 5 = 0101
{1,0,0,1}, //SparkFun Input # 9 = 1001
{1,0,1,1}, //SparkFun Input # 13 = 1101
{0,1,0,0}, //SparkFun Input # 2 = 0100

Using that knowledge, appropriate wiring and a for loop (along with some bitwise operations and direct port access) would free up quite a bit of memory (relative to the available memory that is...) and seriously speed things up..  There's plenty of posts on the subjects on the forums, but feel free to ask away after trying some things out.
Logged

Offline Offline
God Member
*****
Karma: 2
Posts: 711
a, b = b, a+b
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

OK, so I think I improved my code (in theory... it just doesn’t work yet. is giving back semi-random values... might have a wrong port selected or something) and since I will let this rest until tomorrow, I thought I would check to see whether someone can tell me if I am on the right path or not.

I need the array of binary values, because of the wiring of my sensors. Using the array allows me to call the pins in the order I want to read them, rather than in sequential order. This saves me a step of re-ordering them later. (Do you think this is silly? as in, am I wasting processing power on the arduino, as I could just do this on my computer?)

I am using DDRB to set pins 4,5,6,7 of register B of the arduino mega high (corresponding to pins 10,11,12,13)

I then use PORTB to write the binary values stored in muxInput[] to the digital outputs.

Is this correct so far?

Quick question to see if I got this right PORTB = B01000010 will set pin 1 & 6 of Port B high. Correct?

I am using this data sheet for selecting ports. Does anyone know any more extensive documentation on this? (for the arduino mega?)
https://spreadsheets.google.com/ccc?key=roX9D5pGUrS4muSBJysz1QQ#gid=0

Anyway, here is the code:


Quick question to see if I got this right PORTB = B01000010 will set pin 1 & 6 of Port B high. Correct?

I am using this data sheet for selecting ports. Does anyone know any more extensive documentation on this? (for the arduino mega?)
https://spreadsheets.google.com/ccc?key=roX9D5pGUrS4muSBJysz1QQ#gid=0

Anyway, here is the code:


Code:

  int muxInput[16]={ B00000000, B01000000, B10000000, B11000000, B00010000, B01010000, B10010000,
  B11010000, B00100000, B01100000, B10100000, B11100000, B00110000, B01110000, B10110000, B11110000};

  
//Signal pin for each individual multiplexer
int mux1 = 3;
int mux2 = 2;
int mux3 = 1;
int mux4 = 0;

void setup(){
  
  DDRB = B11110000;

//initate serial
  Serial.begin(9600);
}

void loop(){


//read the multiplexers & display the values

/*
I only use 8 pins of multiplexer 4, thats why
I have two different conditions for i < 8 and i < 15
Depending on how many sensors you are reading, you will
probably want to change this.
*/


  for(int i = 0; i < 16; i ++){
    if (i < 8) {
     // read all 4 multiplexers
     setMux(i);
      Serial.print(analogRead(mux1));
      Serial.print(",");
      Serial.print(analogRead(mux2));
      Serial.print(",");
      Serial.print(analogRead(mux3));
      Serial.print(",");
      Serial.print(analogRead(mux4));
     Serial.print(",");
    }
       else  if (i < 15) {
         //read multiplexer 1,2 & 3 only
     setMux(i);
      Serial.print(analogRead(mux1));
      Serial.print(",");
     Serial.print(analogRead(mux2));
      Serial.print(",");
      Serial.print(analogRead(mux3));
    Serial.print(",");
    }
     else {
       //read multiplexer 1,2 & 3 and then start new line
         setMux(i);
      Serial.print(analogRead(mux1));
     Serial.print(",");
      Serial.print(analogRead(mux2));
      Serial.print(",");
      Serial.print(analogRead(mux3));
      Serial.println(" ");
    }
  }
}


//function for setting control pins
void setMux(int input){
  PORTB = muxInput[input];
  }
« Last Edit: August 08, 2011, 07:27:04 pm by fkeel » Logged


Southern Ontario
Offline Offline
Sr. Member
****
Karma: 2
Posts: 279
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I need the array of binary values, because of the wiring of my sensors. Using the array allows me to call the pins in the order I want to read them, rather than in sequential order. This saves me a step of re-ordering them later. (Do you think this is silly? as in, am I wasting processing power on the arduino, as I could just do this on my computer?)

I haven't read the whole post, but I will comment on this...  It seems logical to me to wire up the sensors you want to read in the order you want to read them... that way there's no guessing involved.  Read mux #13 and you are reading sensor #13.  This would let you essentially write the integer value (in binary) to the port select pins (hook them up appropriately to the same PORTx).  It would free up the need to use the matrix as well as make things much much more efficient.  You are writing a whole PORTx in less time than it takes to do a single digitalWrite (experts: please correct me if I'm wrong on any of this)

Edit: after reading, my point recommendation still stands.. Keep in mind that your current matrix has the 'binary' value in reverse.
« Last Edit: August 08, 2011, 07:42:58 pm by nickvd » Logged

Offline Offline
God Member
*****
Karma: 2
Posts: 711
a, b = b, a+b
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset


my application is *very* small. i simply dont have the space to change the cabling. (I am making my own flexible pcb's and adding another layer would make it too bulky)

if you look at the code, I dont use a matrix anymore, but a simple 1d array.

*

am I using DDRB and the PORTB command correctly?  (assuming, that I have identified the correct port...)
Logged


Southern Ontario
Offline Offline
Sr. Member
****
Karma: 2
Posts: 279
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ah... If you're stuck with the cabling as is, then yeah, using the byte array will work just fine..  Just make sure the values are correct (they are currently reversed see below).  You should also use a byte instead of an int, as you only need values from 0-15.
Code:
byte muxInput[16]={ // byte because we only need values from 0 to 15
B00000000, // 0
B01000000, // 64
B10000000, // 128
B11000000, // 192
B00010000, // 16
B01010000, // 80
B10010000, // 144
B11010000, // 208
B00100000, // 32
B01100000, // 96
B10100000, // 160
B11100000, // 224
B00110000, // 48
B01110000, // 112
B10110000, // 176
B11110000  // 240
};

I can't speak to the mega as I have never dealt with it, but the answer will be in the datasheet for the atmega chip smiley

Edit:  As for the wiring, you also need to be sure to wire up the mux select pins to the low end of the port (PortXpin0-3), mux S0 -> PortPin0, mux S1 -> PortPin 1, etc...
« Last Edit: August 08, 2011, 08:00:19 pm by nickvd » Logged

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 240
Posts: 24428
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
You should also use a byte instead of an int, as you only need values from 0-15.
Code:

byte muxInput[16]={ // byte because we only need values from 0 to 15
   B00000000, // 0
   B01000000, // 64
   B10000000, // 128
   B11000000, // 192

Zero to fifteen?
Logged

"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

Offline Offline
God Member
*****
Karma: 2
Posts: 711
a, b = b, a+b
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

well. i got the code working...

Code:

//array which I will send to port A

 byte muxInput[16]={
  B00000000, B00100000, B00010000, B00110000,
  B10000000, B10100000, B10010000, B10110000,
  B01000000, B01100000, B01010000, B01110000,
  B11000000, B11100000, B11010000, B11110000

};
 
//Signal pin for each individual multiplexer
int mux1 = 3;
int mux2 = 2;
int mux3 = 1;
int mux4 = 0;

void setup(){

//set the pins I use as output
  DDRA = B11110000;

//initate serial
  Serial.begin(9600);
}

void loop(){


//read the multiplexers & display the values

/*
I only use 8 pins of multiplexer 4, thats why
I have two different conditions for i < 8 and i < 15
Depending on how many sensors you are reading, you will
probably want to change this.
*/


  for(int i = 0; i < 16; i ++){
   if (i < 8)    {
     // read all 4 multiplexers
     setMux(i);
      Serial.print(analogRead(mux1));
      Serial.print(",");
      Serial.print(analogRead(mux2));
      Serial.print(",");
      Serial.print(analogRead(mux3));
      Serial.print(",");
      Serial.print(analogRead(mux4));
     Serial.print(",");
    }
       else  if (i < 15) {
         //read multiplexer 1,2 & 3 only
     setMux(i);
      Serial.print(analogRead(mux1));
      Serial.print(",");
     Serial.print(analogRead(mux2));
      Serial.print(",");
      Serial.print(analogRead(mux3));
    Serial.print(",");
    }
     else {
       //read multiplexer 1,2 & 3 and then start new line
         setMux(i);
      Serial.print(analogRead(mux1));
     Serial.print(",");
      Serial.print(analogRead(mux2));
      Serial.print(",");
      Serial.print(analogRead(mux3));
      Serial.println(" ");
    }
  }
}


//function for setting control pins
void setMux(int input){
  PORTA = muxInput[input];
  }


This is still quite slow. Not sure if it inproved anything over my original code. I assume my limiting factor is that I am running 56 sensors over on analog to digital converter.

As far as the code goes, is there anything obvious I could improve to speed things up?

p.
Logged


Wellington, New Zealand
Offline Offline
Sr. Member
****
Karma: 1
Posts: 404
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I would say that the main speed killer is the use of Serial.print().  You should get a massive boost in performance if you avoid sending data over the serial link every loop.

If you must use Serial.print() then bumping the baud rate up to 115200 will give you some performance improvement.

Code:
Serial.begin(115200);
Logged


Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 240
Posts: 24428
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Another speed improvement you could make is to interleave printing with analogue reads.
This means breaking up the "analogRead" function into its three basic functions, namely:
1) input mux setup and conversion start
2) wait for conversion complete (busy wait)
3) read result.

However, this only takes about the same time as it takes to transmit a single bit at 9600, so the saving isn't that big.
Logged

"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

Pages: 1 [2]   Go Up
Jump to: