Advice needed for taking input from 53 LDRs..

moorea21

Senior Member
I may need to make a linear array of 53 4mm LDRs, for reasons I'll go into if anyone is really really curious. Only 1 of them will see light at any time, and their outputs will be treated strictly as on or off.

Is there some way of multiplexing this number of inputs, and outputting the address of the 'on' LDR to a picaxe?
 

Circuit

Senior Member
Lots of ways, I would think. A couple of 40X2 PICAXEs would have enough inputs to handle your array of LDRs if they are wired up to give a 1 or 0 output as you indicate (I presume you do not need ADC functionality to detect them). You could also do this with three MCP20318 16-bit I2C expanders or use shift registers. Okay, I am really really curious; what do you want to do with a linear array of 53 LDRs? Actually, if you "expand" (or expound...) on your requirements you may get a more helpful answer.
 

premelec

Senior Member
Please specify LDRs are just on/off resistance... and reaction time... you might get away with a few [8] 8 bit DAC ladders - and what's up?
 

moorea21

Senior Member
Okay, you asked for it...:)

I have a recurring shoulder problem that severely limits how long I can practice playing my violin (was down to 15 minutes every few days last time I tried.)

So I've been designing a violin synthesiser, (see my other posts) that allows me to play a 'violin' shaped object with notes in the right place without using a bow (pressing a string to a fret makes the note.) This should releive the stress of (for me) trying to read sheet music, finding the notes, and playing them well. I can practice learning a tune without the many hours of squinting, shoulder pain, and swearing that usually accompanies it.

The other side of this is finding the notes themselves... I can do that by feel fairly well, but I am terrible at reading sheet music, so I wanted to find a way of displaying the notes to be played, in real time, on the fingerboard itself.

An ideal way to learn to transcribe/ compose/ play a violin would be to whistle a melody and have it appear on the fingerboard as you whistle. I have a peice of software that does an excellent job of visualising the pitch of my whistling on screen as a thin coloured line (overtone analyzer), all I needed is a way of getting that information off the screen and into a picaxe to tell the appropriate LEDs to light up, in real time.

So as I whistle a note, that note's LED's light up on the fingerboard; I could then play the notes, thereby getting used to the notes locations, and at the same time learning/composing music in a very flexible, intuitive way. Basically if I can whistle it, I can play it.

I've tried using 'Processing' to write a programn to do that, but it's unbelievably slow at it (I need it to report the Y position of the trace maybe 20 - 50 times a second, it prefers 6 - 12 times a minute;) I dont think its ever going to be fast enough, so I thought maybe I could attach an array of LDRs onto the screen and read the trace that way. I need 53 notes, on my screen each note is 5mm apart, so 53 5mm LDR's suitably arranged should do it.
 

moorea21

Senior Member
This is a screenshot of what it looks like. The code I wrote looks at a vertical slice of screen at Y = 280 px, itterates through all the rgb values until it finds the one thats Red = 71 (best identifier of the blue line), then sends that to the picaxe to quantise to a note value and output to leds via 2 max27219s. Ineed to be able to show transient notes of maybe 1/20th of a second, so I think a sampling rate of 1 - 2.5 times that may be okay.
 

Attachments

AllyCat

Senior Member
Hi,

LDRs are slow, insensitive and have a wide acceptance angle (bad for imaging). You might want them to be ON/OFF but in practice they will have some leakage resistance even in total darkness and they don't drop to zero ohms even in direct sunlight. Also, most types of resistance array need a diode at each node (i.e. LDR) or at least every row/column to avoid undesired parallel/series paths.

Photo-transistors might be a better choice because they are smaller, more sensitive, with a built-in lens and a unidirectional (diode) characteristic that might help multiplexing. But to be honest I would be looking for a totally different "solution" to your requirements, partly because I don't think your "trace" will be bright enough.

Cheers, Alan..
 

Circuit

Senior Member
Two 40X2 PICAXEs would certainly give you sufficient inputs and they can talk to each other in a variety of ways. Reading whole ports at a time and comparing for change against the last byte values may do the trick. What I don't yet fathom is quite how you intend to get a digital binary output from an LDR without further circuitry. Have you any proposals on this aspect?
 

BESQUEUT

Senior Member
I may need to make a linear array of 53 4mm LDRs, for reasons I'll go into if anyone is really really curious. Only 1 of them will see light at any time, and their outputs will be treated strictly as on or off.

Is there some way of multiplexing this number of inputs, and outputting the address of the 'on' LDR to a picaxe?
Why not using a linear array
(datasheet)?
Quite easy to interface and very quick...
 

moorea21

Senior Member
That linear array looks good, have you used one at all?

I didnt expect to plug the LDRs straight into pins, I was thinking maybe some kind of aplification, something to basically turn a small difference into a big one...
 

BESQUEUT

Senior Member
I've tried using 'Processing' to write a programn to do that, but it's unbelievably slow at it (I need it to report the Y position of the trace maybe 20 - 50 times a second, it prefers 6 - 12 times a minute;) I dont think its ever going to be fast enough,
Never used 'Processing' but seems to be quite slow... Can you publish your sketch ?
May try to do that with Visual Studio... Would certainly be quick enought...

A better way would be to analyse sound via an FFT transformation and directly send data to the Picaxe...
https://www.codeproject.com/Articles/58148/Sound-Scanner-and-FFT-Analyzer

https://www.codeproject.com/Articles/32172/FFT-Guitar-Tuner

https://www.codeproject.com/Articles/1107480/DSPLib-FFT-DFT-Fourier-Transform-Library-for-NET
 
Last edited:

AllyCat

Senior Member
Hi,
That linear array looks good, have you used one at all?
Not me either, but Edmunds did, see post 10 in this long thread (page 2 did rather wander OT). However, not an easy optical design and the "camera" version (with a lens) is quite expensive.

I didnt expect to plug the LDRs straight into pins, I was thinking maybe some kind of aplification, something to basically turn a small difference into a big one...
53 amplifiers? Otherwise it's potentially just "(small) garbage in ... (big) garbage out". ;)

I don't think you're specified the PICaxe, but even the 08M2 has three "touch" inputs, so maybe it could make a Theremin (which have always been notoriously unstable), but wandering OT again.

Cheers, Alan.
 

premelec

Senior Member
Oh my I see a violin Theramin in the future ;-0 - I have salvaged but not used lots of linear array units from old scanners - there's a lens and front surface mirrors that do the work of getting an image to the linear array...
 

AllyCat

Senior Member
Hi,

there's a lens and front surface mirrors that do the work of getting an image to the linear array...
But not in that particular sensor which needs a conventional lens at the front (or I planned a "pinhole camera" concept, however it's still on my "todo" list).

Cheers, Alan.
 

hippy

Technical Support
Staff member
The code I wrote looks at a vertical slice of screen at Y = 280 px, itterates through all the rgb values until it finds the one thats Red = 71 (best identifier of the blue line), then sends that to the picaxe to quantise to a note value and output to leds via 2 max27219s.
Why not have your software send what is detected via serial, then there would seem to be no need to have any LED's or LDR's.
 

moorea21

Senior Member
Ok, lots to reply to

Hippy:
The software as written is supposed to send the data via serial (eventually; not written that bit yet). The LEDs are what light up on the fingerboard to show me which notes to play. Not sure I understand you there, sorry.

Alan:
The camera version in Besquets link is not that pricey really, certainly an option.

'53 amplifiers? Otherwise it's potentially just "(small) garbage in ... (big) garbage out". '

I may be a bit slow this morning; are you saying this is a bad idea? Or just that light detectors without amplifiers would be rubbish? If its the second, I totally agree.

Besqueut:
Heres the sketch:-

Code:
 import java.awt.Robot;
  import java.awt.AWTException;
  Robot robot;

  void setup() {
    try {
    robot = new Robot();
  }
  catch (AWTException cause) {
    exit();
    throw new RuntimeException(cause);
  }
  }
  //
  void draw() {
  for (int i = 230; i < 601; i++) 
  {
    int p = robot.getPixelColor(280 , i).getRed();

    if (p == 71) {  //      71, 182, 240 is rgb to look for
      println(i);
      break;
      }
  }
  }
The values for X ( 230 - 600) are wrong; they were just to test a small area with a recording with very little frequency range. The actual size would be (160 - 1060) approx.

I've attached the image I was using to test it with, I opened the image and just moved it around on screen.

Processing seems to be slow, yes. If you mean C++ when you are talking about visual studio, that would I'm sure be the best option. It's one I hadn't considered, as I only started using C and Java a couple of weeks ago, never tried C++. But if you are willing to try, that would be very much appreciated.

I tried many FFT programs on PC, almost none are configured to work well with human vocal sounds, and of those that are, only Overtone Analyzer does a good job of it. If there was a way to do all this on one processor, without PC + windows + sensors etc, I would be all for it. But as that's all beyond my current capabilities, and the actual usefulness of this whole project is unproven, I decided to use what I could find.
 

Attachments

Last edited:

AllyCat

Senior Member
Hi,

are you saying this is a bad idea? Or just that light detectors without amplifiers would be rubbish?
I was suggesting that trying to "multiplex" (i.e. combine together) a number of LDR signals before a smaller number of amplifiers is not likely to work. It's the amplification before multriplexing that's likely to be needed, not amplification for the detection as such, i.e. one PICaxe (ADC) input pin per LDR could work fine (but need a number of PICaxes).

Edmunds spent lots of time getting his code to work "fast" with that sensor, but I don't think he ever needed (or got) anything near to the full resolution of 128 pixels. The thread I linked above did rather wander Off Topic and I think there might have been another one with more detail, at much the same time.

Edit: Yes, at least three more threads concerning the same sensor/project: here , here and here.

Cheers, Alan.
 
Last edited:

hippy

Technical Support
Staff member
Hippy:
The software as written is supposed to send the data via serial (eventually; not written that bit yet). The LEDs are what light up on the fingerboard to show me which notes to play. Not sure I understand you there, sorry.
That was my misunderstanding of what the LDR's were monitoring.

So, if I have understood it right, you are trying to get what 'overtone analyser' shows on screen sent to the LED's on the violin. If we assume that you are not going to have a huge ribbon cable running from your violin there will be some serial conversion in there. So it's two parts; get what's shown on screen sent as a serial indicator of note, get that serial converted to an LED on the violin.

Using LDR's seems to be a kludge to get round not being able to determine what's on the screen quickly enough by a program running on the PC. The LDR solution seems to me to be an expensive, overly complicated, and probably won't work well, alternative to creating a PC program which does run quickly enough.

I would focus on getting that PC program working fast enough.

On the violin side it doesn't seem that any MAX7219 is needed, A PICAXE could easily receive serial and drive the 56 LED's directly and the wiring would be no more complicated.

Whistling, having to use 'overtone analyser', and then having something to decode what's on screen and send that to the violin, seems a quite complicated workflow. Especially when you could just fire up a MIDI player or sequencer, send the note data from that straight into the violin, or through another PICAXE to simplify what's actually in the violin.

A MIDI to 56-LED controller should be fairly easy to accomplish.
 

moorea21

Senior Member
The second paragraph summarises it correctly. I totally agree with you in the 3rd and 4th paragraph. Kludge is a good word for it I think...

I've already got the max7219 side of things working, I didnt realise I could address that many LEDs with a picaxe; would that involve i2c??

I could use MIDI, but the point of the project really is 'if I can whistle it, I can play it'. If I use a MIDI instrument, I'm still faced with the same problem of having to know which notes to play in order to make the melody, just on a different instrument. The only instrument I can play is the violin (if you don't count whistling as an instrument,) so that would then actually be making the process more complicated, not less. Should have learned the piano really...

As you said, getting a program on the PC to work, probably using a faster, more direct language than 'processing's java would be the best strategy; I'm hoping Besqueut can lead the way on that, as I think it would take a lot of experience with C++ to carry it off. I'm willing to have a go, just don't fancy my chances!
 

hippy

Technical Support
Staff member
I've already got the max7219 side of things working, I didnt realise I could address that many LEDs with a picaxe; would that involve i2c??
No, no I2C required. Just wire a 7x8 matrix of LED's direct to a PICAXE then set two pins, high and low, to pass current through the appropriate LED.
 

AllyCat

Senior Member
Hi,

Or just 9 pins can drive up to 72 LEDs with a Charlieplex: Connect one LED from each pin to every other pin (9 x 8 = 72), drive one pin High and another Low to light the desired LED, with all the other pins Tr-State/floating (set as inputs).

Cheers, Alan.
 

BESQUEUT

Senior Member
As you said, getting a program on the PC to work, probably using a faster, more direct language than 'processing's java would be the best strategy; I'm hoping Besqueut can lead the way on that, as I think it would take a lot of experience with C++ to carry it off. I'm willing to have a go, just don't fancy my chances!
OK : will have a try, but give me some days...
Another way (sorry no Picaxe involved...) use a Teensy, with the audio library
Clic on the left : analyse / fft256, fft1024 or notefreq
Can be programmed with Ard..o IDE
20$ to 30$ for the teensy, +15 $ for the audio shield.
Can out direct to WS2812 LED strip. (Can be 2 x 72 pixels x 50 cm...)
 
Last edited:

BESQUEUT

Senior Member
Take your time, I'm just happy people are prepared to help!
First try. This will find first pixel in the screen close to the selected color.
Code:
Public Class Form1
    Dim SCbounds As Rectangle
    Dim screenshot As System.Drawing.Bitmap
    Dim graph As Graphics

    Private Sub Capture_Click(sender As Object, e As EventArgs)
    End Sub

    Private Sub Color_Click(sender As Object, e As EventArgs) Handles Color.Click
        ColorDialog1.ShowDialog()
        TextBox1.Text = ColorDialog1.Color.ToString
        Me.BackColor = ColorDialog1.Color
    End Sub

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        Me.BackColor = Drawing.Color.Red
        TextBox1.Text = Drawing.Color.Red.ToString
        SCbounds = Screen.PrimaryScreen.Bounds
        screenshot = New System.Drawing.Bitmap(SCbounds.Width, SCbounds.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb)
        graph = Graphics.FromImage(screenshot)
        Timer1.Enabled = True
    End Sub

    Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
        Dim C As Color
        Dim X As Integer
        Dim Y As Integer
        Dim R1 As Integer
        Dim G1 As Integer
        Dim B1 As Integer

        Dim D As Long

        graph.CopyFromScreen(SCbounds.X, SCbounds.Y, 0, 0, SCbounds.Size, CopyPixelOperation.SourceCopy)
        R1 = Me.BackColor.R
        G1 = Me.BackColor.G
        B1 = Me.BackColor.B
        For X = 0 To screenshot.Size.Width - 1
            For Y = 0 To screenshot.Size.Height - 1
                C = screenshot.GetPixel(X, Y)

                D = (R1 - C.R) ^ 2 + (G1 - C.G) ^ 2 + (B1 - C.B) ^ 2
                If D < 1000 Then
                    Me.Text = C.ToString & "  D=" & D & " X=" & X & "  Y=" & Y
                    Exit Sub
                End If
            Next Y
        Next X

        Me.Text = "Not found"
    End Sub
End Class
Need 1 texbox and 1 button on a form + 1 Timer set to 50ms :
Violin.jpg
Can you try this with V Studio ?
 

Attachments

Last edited:

moorea21

Senior Member
Ah, looks like VB... Is it VB.net? I have VB6 only, but I could find VB.Net and try it.

So this code finds the 1st pixel of a colour specified in the text box? It looks like it looks at the whole screen? Is the format for entering the colour R,G,B?

Well done for coming up with something so quickly, I'll be happy to test this. Where is the best place to download visual studio? And what version should I get?
 

BESQUEUT

Senior Member
I used VB6 since many (too much...) years, and still use it sometimes. But have problems with W7 and even more with W10...
https://www.visualstudio.com/fr/free-developer-offers/
Visual studio Community 2017 is free from Microzoft.
Send me your e-mail by private mail so I can send you a ready to use project.
YES color object have Red, Green and Blue properties.
But I use a ColorPicker, so you can simply chose a color with two clicks.
The code find first pixel close to the required color, and YES it can scan full screen if necessary.
The closeness is actually 1000, but you can chose any other value.
Screen is scanned each 50 ms, so 20 times a second with no significative CPU load.

Will be even easier to chose an X column and scan only that column.
Then we have to use a Comm object to send data to the COM port...
 
Last edited:

moorea21

Senior Member
Ive sent a PM with my email, visual studio installer currently doing its thing.
I never knew VB could be fast! If someone had asked me 'what language would do this job' I'd have never thought VB.
When you say 'The closeness is actually 1000', what do you mean?
Would the code run even faster if was only looking for the red component of RGB? And would it also be quicker if it only had to scan the 1px wide 'slice' instead of a larger area?
Looking forward to this!

Am I right in thinking that I only need to install 'Universal Windows Platform Development' and '.NET desktop development' to get this to run and be editable?
 

hippy

Technical Support
Staff member
Will be even easier to chose an X column and scan only that column.
Possibly more work than you wish to do but you could probably scan the whole screen once at start-up when showing the 'overtone analyser', determine where things are on that, where the 'piano keys' are, and where the visual data will be.

After that the main code only has to check just 56 pixels which relate to the LED's. Background colour if not selected, non-background colour if they are.

As you suggest, you might be able to just grab the part of the screen image which has the column of pixels so could deliver quite a fast frame rate sampling.
 

BESQUEUT

Senior Member
When you say 'The closeness is actually 1000', what do you mean?
It's sometime difficult to find the exact color to find.
So I compute a distance from a color to another :
D=SQRT((R2-R1)^2 + (G2-G1)^2 + (B2-B1)^2)
Actually, the 1000 value equate a mean difference of sqrt(1000)=32

For example :
R1=255 G1=0 B1=128
R2=252 G2=0 B2=124
D*D=3*3 +0*0 + 4*4 = 25
D=5
 

moorea21

Senior Member
I can't test the code at the minute, as I'm having to delete a lot of programs to make room for visual studio, including photoshop, which I now need to make test images for your code. Ironic.

I notice that your equation above differs from the one in the version you posted here a few posts back, which was

D = (R1 - C.R) ^ 2 + (G1 - C.G) ^ 2 + (B1 - C.B) ^ 2

Above you have

D=SQRT((R2-R1)^2 + (G2-G1)^2 + (B2-B1)^2)

Which of these is correct? Maybe I'm tired and missing something in the rest of the code that means they come out the same?

What would happen if
If D < 1000 Then

was changed to
If D < 5 Then

Would it sometimes fail to find the 'trace'(blue) line? You say its sometimes difficult to find the exact colour, I'm not sure yet how close to exact it needs to be.
 

BESQUEUT

Senior Member
Possibly more work than you wish to do but you could probably scan the whole screen once at start-up when showing the 'overtone analyser', determine where things are on that, where the 'piano keys' are, and where the visual data will be.

After that the main code only has to check just 56 pixels which relate to the LED's. Background colour if not selected, non-background colour if they are.

As you suggest, you might be able to just grab the part of the screen image which has the column of pixels so could deliver quite a fast frame rate sampling.
Just dowloaded Overtone Analyser to have a look.
Overtone.jpg
I have to find Pixels NOT black, NOT Grey and find the middle of the peak...
Better to wait for screen copy from moorea...
 

BESQUEUT

Senior Member
I can't test the code at the minute, as I'm having to delete a lot of programs to make room for visual studio, including photoshop, which I now need to make test images for your code. Ironic.
YES, I know : this one is a little bigger than VB6...
I notice that your equation above differs from the one in the version you posted here a few posts back, which was

D = (R1 - C.R) ^ 2 + (G1 - C.G) ^ 2 + (B1 - C.B) ^ 2

Above you have

D=SQRT((R2-R1)^2 + (G2-G1)^2 + (B2-B1)^2)

Which of these is correct? Maybe I'm tired and missing something in the rest of the code that means they come out the same?

What would happen if
If D < 1000 Then

was changed to
If D < 5 Then

Would it sometimes fail to find the 'trace'(blue) line? You say its sometimes difficult to find the exact colour, I'm not sure yet how close to exact it needs to be.
C is the name of the Color object
C.R is the RED property of a color object
So R2=C.R
Also note that (R2-R1)^2 = (R1-R2)^2

D is simply the distance in the color cube.
But for the code, it is the same thing to test D or D*D, so for speed optimization, I do not use the SQRT...

If you test for D<5 then each differences for R, G and B components have to be 1 or less, or at least 1can be 2 if the two others are zero.

I think you can try few values.

If you know exactly what is the color to find, you can use the EQUALS method of the color object
 
Last edited:

moorea21

Senior Member
'I have to find Pixels NOT black, NOT Grey and find the middle of the peak...'

If you look at post #7 on here, you will see overtone analyzer set up how I use it. No need to look for anything other than 2px height of rgb = 71,182,240 at x = 280px, and between y = 160px - 1030px. On my screen anyway!

Press F10, or go to options (flower type shape on top bar of analyzer)
In analyzer view>Analyzer Display:-
tick long term view AND short term view
tick 'pitch, untick spectrum and average spectrum
tick 'piano' in long term view
Set 'scroll mode' to paging

In 'Scale', set scale range from G3 to B7, and frequency display to 'logarithmic'

In main window, under 'view', untick everything except 'piano' and 'timescale'
Lastly, on the main window, click on the grey vertical line that divides long term view from short term view, move it as far left as it will let you.
I think thats everything. Time for bed I think...
 
Last edited:

BESQUEUT

Senior Member
'I have to find Pixels NOT black, NOT Grey and find the middle of the peak...'

If you look at post #7 on here, you will see overtone analyzer set up how I use it. No need to look for anything other than 2px width of rgb = 71,182,240 at x = 280px, and between y = 160px - 1030px. On my screen anyway!

Press F10, or go to options (flower type shape on top bar of analyzer)
In analyzer view>Analyzer Display:-
tick long term view AND short term view
tick 'pitch, untick spectrum and average spectrum
tick 'piano' in long term view
Set 'scroll mode' to paging

In 'Scale', set scale range from G3 to B7, and frequency display to 'logarithmic'

In main window, under 'view', untick everything except 'piano' and 'timescale'
Lastly, on the main window, click on the grey vertical line that divides long term view from short term view, move it as far left as it will let you.
I think thats everything. Time for bed I think...
Tried that, but now nothing on the screen, except green activity in the microphone volume control...
I have to sleep a little, and wait for your screen copy...
 

moorea21

Senior Member
Yes, sorry. My screen shot was of an audio track playing back. Load an mp3 of singing, humming, or whistling, it'll give you a blue horizontal line etc.
 
Top