Go Down

### Topic: Is it possible to read 218 independent inputs? (Read 10401 times)previous topic - next topic

#### mpeuser

#15
##### Aug 13, 2010, 07:04 pmLast Edit: Aug 13, 2010, 07:05 pm by mpeuser Reason: 1
I once tested the loop:

Code: [Select]
`digitalWrite(clock, LOW)digitalRead(data)digitalWrite(clock, HIGH)`
There is a lot of overhead in the underlaying C-Code...
As this was some time ago my memory might be unprecise - I shall repeat the meassurement and report here again :-)

#### AWOL

#16
##### Aug 13, 2010, 07:19 pm
It's a lot easier to speed up a digital read than it is to speed up an analogue one
"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.
I speak for myself, not Arduino.

#### 2stl

#17
##### Aug 13, 2010, 07:34 pm
Wow... Thanks guys.

However, the ability to detect simultaneous presses is very essential. And 36ms isn't very good, but is much more acceptable than 'non-simultaneosity'. Including the pedals and effects, sometimes it will be necessary to detect 5 simultaneous events or more.

Maybe the "PISO" method, even if a little bit "delayed", is the best bet in this case. Is it possible to detect simultaneous events this way?

Also, I planned to do this while i'm on vacation, as a hobby, however, I don't know if 1 month will be enough to finish this, because it looks way harder than I thought.

Is there a noob tutorial teaching in details how to do this (PISO) in practice?

Thanks guys.

#### UltraMagnus

#18
##### Aug 13, 2010, 07:47 pm
Quote
All right, there is another not so well known appproach, using an analogue technique. You can add a resistor to each of the keys to a common voltage, adding the current through them. As you have to identify multiple keys, the values have to be logarithmic which limits this approach to less than 10 keys

this will take far too long, the arduino only has a single ADC (that is multiplexed already) and it is a very slow ADC.  It could work with banks of flash ADCs, but that would be expensive.

Latches and encoders could work, it would be much faster than shift registers anyway.  Just tri-state all the latches apart from the one you want to read.  The encoder isn't necessary but saves port space.

You could also use the Intel 8255, which gives you 3 GPIO ports from one, but it is rather an old chip, I don't know if the is a more modern alternative.

#19

#### AWOL

#20
##### Aug 13, 2010, 09:24 pm
Speed
"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.
I speak for myself, not Arduino.

#### 2stl

#21
##### Aug 13, 2010, 09:46 pm
Thanks AWOL.

I've found some nice documentations about parallel shifting, including a nice official example (http://www.arduino.cc/en/Tutorial/ShiftIn), however, i must know if *any* 8-bit parallel-to-serial register will do the job, and if the procedure to add more than 2 register is simply to reproduce the same arrangement as the second register.

#### AWOL

#22
##### Aug 13, 2010, 10:29 pm
I did a quick and only moderately representative test, of digital reads vs analogue reads.
The test is simplified in that neither case assembles readings into storable bytes, but the overhead would be minimal, and fairly constant in either case.
Code: [Select]
`const int N_INPUTS = 218;const int clockPin = 2;const int dataPin  = 3;const int analoguePin = 0;void setup (){  pinMode (clockPin, OUTPUT);  digitalWrite(clockPin, LOW);  pinMode (dataPin, INPUT);  Serial.begin (9600);  time ();}void loop () {}void time (){  unsigned long start = micros ();  unsigned long elapsed;  start = micros ();  for (int i = 0; i < N_INPUTS; ++i) {    singleDigitalRead ();  }    elapsed =  micros () - start;  Serial.print ("digital loop ");  Serial.println (elapsed);  start = micros ();  for (int i = 0; i < N_INPUTS; ++i) {    singleAnalogueRead ();  }    elapsed =  micros () - start;  Serial.print ("analogue loop ");  Serial.println (elapsed);  }void singleDigitalRead (){  digitalWrite(clockPin, LOW);  (void)digitalRead (dataPin);  digitalWrite (clockPin, HIGH);  }void singleAnalogueRead (){  (void)analogRead (analoguePin);}`
And the results are:
Quote
digital loop 2856
analogue loop 24516

Times in microseconds.

As predicted, the digital read is considerably quicker than the analogue one (better than 8x faster), and could be quicker still with some simple modifications.

Again, add in a small overhead for setup and byte packing, but you're still heading for a whole keyboard scan rate of two or three hundred Hertz.
"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.
I speak for myself, not Arduino.

#### 2stl

#23
##### Aug 13, 2010, 10:56 pm
Wow... Am I wrong, or this is something like 3 milliseconds?? (for the digital input)

Even the analog input is fast enough to me... btw I just found a incredibly nice tutorial on how to use Python to talk to Arduino (http://www.stealthcopter.com/blog/2010/02/python-interfacing-with-an-arduino/) and i'm going to use Python instead of C++ to actually "play" the songs on PC. Zynaddsubfx is 'massive'.

I wonder if the use of parallel to serial registers has some bad limitation though.

Thank you.

#### AWOL

#24
##### Aug 13, 2010, 11:00 pm
Quote

< 40Hz?
"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.
I speak for myself, not Arduino.

#### 2stl

#25
##### Aug 13, 2010, 11:09 pm
Oh... I forgot that the analog input is 'at the mercy' of the clock frequency.

#### mpeuser

#26
##### Aug 14, 2010, 12:35 amLast Edit: Aug 14, 2010, 12:37 am by mpeuser Reason: 1
Sorry for the delay... So I rechecked the reading of a bit from shift register and the scope showed pulses of 14us. This is absolutely compatible with AWOL's measurement and 10 x faster than  I had in mind. What I did formerly was reading out the whole 8 bit register with some complex bit manipulations, which then altogether took 150 us...

Analogue reading: Dont compare apples and oranges! The analogue method will give you 8 readings at a time, so the time for I/O is absolutely comparable!

Remember that the main concern was the mass of chips involved to connect 200+ lines. There is no diference between shift registers and multiplexers. Only the analogue method can reduce that hardware complexity....

#### AWOL

#27
##### Aug 14, 2010, 01:07 am
Quote
The analogue method will give you 8 readings at a time, so the time for I/O is absolutely comparable!

On a ten bit A/D?
"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.
I speak for myself, not Arduino.

#28
##### Aug 14, 2010, 01:47 amLast Edit: Aug 14, 2010, 01:56 am by graynomad Reason: 1
The PISO SRs will work just fine, the only thing is the speed using user C code and that seems to be open to conjecture at present. Certainly if the function was written in assembler it would be fast enough.

Unfortunately the Arduino doesn't have a shiftin() function (I think) to match shiftout() as it's possible a library function like this would be written in assembly (OK unlikely but possible).

So what about using the hardware SPI on the chip. It's little more than a shift register itself, if you organize the 28 external SRs as mentioned, pulse one ditgital pin to latch data into all SRs, then send 28 bytes out the SPI, the data will appear on the MOSI line but that is not even connected. However the output of SR #28 is connected to MISO, so every byte you write causes a byte to be read and you grab it before sending the next byte.

See page 167 of the 328 spec sheet for details.

This will run blindingly fast (up to 4Mbps but probably a bit slower if your line lenghts are long) and should solve the "to slow" problem.

Whatever you do this is going to be a large wiring job though.

Quote
Is it possible to detect simultaneous events this way?

Yep.
Rob Gray aka the GRAYnomad www.robgray.com

#29
Quote