This is one of the precision potentiometers I'll be using in my tube preamp build. They are stepped (like 24 or 27 steps) made with precision film resistors on a small circuit board in there with the stepping mechanism.

I want to get rid of the little nubby sticking up on each pot. I don't have the tools to do this anymore so I'm looking for any suggestions that you might have. I want to get rid of the nubby without damaging the rest of these beautiful things.

#Potentiometer #Help #Suggestions

Analog Siren For Psychedelic Soundscapes

For better or worse, there are a few instruments that have been pigeonholed into specific genres of popular music. For example, banjos are often heard in bluegrass or folk, harmonicas in blues, and…

Hackaday

A detailed view of one of my mixing consoles {Yamaha}

Composed in 85F warming light using my Philips Spot Light which I've had since I was a 17 years old teenager!

#Yamaha #JOYO #Console #mixing #faders #potentiometer #AUX #Auxiliary #BUS #gain #Phantom #Power #48V #technology #Audio #music #signal #flow

What to do when a #volume #potentiometer on a #vintage #headphone #amplifier starts to make "scratch" noises when operated?
Oh look ! My #achievmentunlocked so far today : #Potentiometer based controllers on #Amiga, like atari 8bits and c64 #paddles and 90s area PC flight simulator sticks, will be managed on the next version of #MameMinimix .I didnt even know it was possible on amiga. The code to do this is actually quite complex (watch github if interested) and needed a bit hack to work alongside the lowlevel Api. One other Milestone act is that... hey ! finnaly we can have driving game with actual analog wheel and brakes on Amiga !!! #retrogeek
🌘 學習基礎電子學:打造個人專屬的螢火蟲
➤ 從零開始,用動手實踐點亮學習之夜
http://a64.in/posts/learning-basic-electronics-by-building-fireflies/
作者分享了透過親手製作電子「螢火蟲」,從零開始學習基礎電子學的歷程。他利用 Astable Multivibrator 迴路,結合光敏電阻(LDR)和電位器(Potentiometer),成功調整了 LED 的閃爍時間和亮度,使其能在夜間發光,並優化了能源效率。過程中,他克服了元件故障、模擬器不符預期、焊接煙霧問題,甚至從廢棄電路板上拆卸元件,最終成功製作出多個功能性的「螢火蟲」,重拾了學習新知的熱情與樂趣。
+ 這篇文章太激勵人了!從完全不懂到自己做出會亮的「螢火蟲」,過程中的各種小挫折和解決辦法都寫得非常真實。我也想試試看!
+ 作者分享的學習方法很棒,結合 AI 工具和實際操作,讓電子學不再是枯燥的理論。特別是那個自製的閃爍延遲模擬器,
#電子學 #DIY #學習 #創客 #Astable Multivibrator #LDR #Potentiometer
Learning Basic Electronics By Building FireFlies | theapache64

From missing real fireflies to learning basic electronics and building my own blinking "fireflies"

Annoyingly had a #guitar issues (static noise bursts) during the recording session and eventually had to clean up the volume #pot with a #contact #cleaner. That's not ideal, #potentiometer requires special #protective #lubricant that unfortunately I did not have. I hope it'll be fine if I add the correct solution later.

Arduino MIDI Atari Paddles

Finally, I get to the point where I can do something vaguely musical with my Atari 2600 Controller Shield PCB. This turns it into a simple MIDI CC controller using the Atari paddles.

https://makertube.net/w/dgK7y73KfC1SWc5z2wsJ6x

Warning! I strongly recommend using old or second hand equipment for your experiments.  I am not responsible for any damage to expensive instruments!

These are the key Arduino tutorials for the main concepts used in this project:

If you are new to Arduino, see the Getting Started pages.

Parts list

The Circuit

I’m using my Arduino MIDI Proto Shield which makes connecting everything up pretty straight forward.

Particularly using the TRS version, which means the boards will stack quite neatly.

The Code

This is using the code from Atari 2600 Controller Shield PCB Revisited – Part 3 and combining it with the Arduino MIDI Library to send out a MIDI CC message when the potentiometer values change.

I’ve re-implemented my pot averaging code as a reusable object again but this time I’ve split it out into its own header file implementation. I’ve recreated the complete code below. This can be saved in a header file for simple reuse in other code.

#define AVGEREADINGS 32

class AvgePot {
public:
AvgePot(int pot) {
potpin = pot;
for (int i=0; i<AVGEREADINGS; i++) {
avgepotvals[i] = 0;
}
avgepotidx = 0;
avgepottotal = 0;
}

int getPin () {
return potpin;
}

unsigned avgeAnalogRead () {
unsigned reading = 10*avgeReader(potpin);
avgepottotal = avgepottotal - avgepotvals[avgepotidx];
avgepotvals[avgepotidx] = reading;
avgepottotal = avgepottotal + reading;
avgepotidx++;
if (avgepotidx >= AVGEREADINGS) avgepotidx = 0;
return (((avgepottotal / AVGEREADINGS) + 5) / 10);
}

unsigned avgeAnalogRead (int pot) {
if (pot == potpin) {
return avgeAnalogRead();
}
return 0;
}

virtual unsigned avgeReader (int potpin) {
return analogRead(potpin);
}

private:
int potpin;
unsigned avgepotvals[AVGEREADINGS];
unsigned avgepotidx;
unsigned long avgepottotal;
};

One trick I’ve used (or at least, believe I’ve used – I’m not really a C++ person) is the use of a virtual function avgeReader(). By default this implementation calls straight out to the standard Arduino analogRead() function, but by being virtual means that it is possible to create a new class based on this one that can override that function with a bespoke routine.

This is what I’ve done to link this to the atariAnalogRead() function from my previous code as shown below. Note that, as I understand things, constructors aren’t inherited, so a new constructor is required to link back to the base class’s original.

class AtariPot : public AvgePot {
public:
AtariPot (int potpin) : AvgePot (potpin) {}

unsigned avgeReader(int potpin) override {
return atariAnalogRead(potpin);
}
};

I can then set up four instances of this new AtariPot class for each of the paddle controls.

AtariPot *atariPot[NUMPADS];

void setup() {
for (int i=0; i<NUMPADS; i++) {
atariPot[i] = new AtariPot(pad_pins[i]);
}
}

Reading each atari pot is then just a case of calling the correct function for each instance.

void loop() {
for (int i=0; i<NUMPADS; i++) {
val = atariPot[i]->avgeAnalogRead() >> 3;
}
}

I’m shifting the result >> 3 to reduce the 10 bit value to a 7 bit value for use as a MIDI CC. This takes the range 0..1023 down to 0..127.

There is a table at the start that defines which MIDI CC message corresponds to which paddle controller. By default, I’ve used the following:

int midiCC[4] = {
0x01, // Modulation wheel
0x07, // Channel volume
0x0B, // Expression control
0x10, // General purpose control 1
};

Find it on GitHub here.

Closing Thoughts

I’m not sure quite how practical using Atari paddles for a MIDI controller really is, but that hasn’t stopped me before and it hasn’t stopped me now.

The video shows two paddles controller modulation and volume for a MiniDexed. So it does appear to work.

I’ve still a few other odds and ends I want to try:

  • It would be interesting to see how this contrasts with the simpler step of using a resistor to create a potential divider from the paddle as described in the original Atari 2600 Controller Shield PCB Build Guide. It would probably work fine too and would be a lot simpler in code terms.
  • I still want to do something with the Atari keypads!

I must admit there is also a part of me thinking that if I could find some paddle controllers that were perhaps no longer fully functional, I would be able to take them apart and stick a small microcontroller in the paddle housing itself…

Kevin

#arduinoUno #atari #define #midi #potentiometer

Atari 2600 Controller Shield PCB Revisited – Part 3

Following on from Atari 2600 Controller Shield PCB Revisited – Part 2 someone on Mastodon made the point that the reason they tended to use RC circuits to read paddles “back in the day” was due to the expense of ADCs.

Which triggered a bit of an “oh yeah” moment.

The whole point was not to worry about the analog levels at all, and just measure the time it takes for the pin to read HIGH again.

So this looks back at removing the whole ADC thing with a simple “if (digitalRead(pin))” condition!

Warning! I strongly recommend using old or second hand equipment for your experiments.  I am not responsible for any damage to expensive instruments!

If you are new to Arduino, see the Getting Started pages.

The Code

The overarching principles are the same as for Atari 2600 Controller Shield PCB Revisited – Part 2 but instead of all the bespoke code to read the analog to digital converter, I’m relying on the following:

  • A digital input pin has a threshold for which the input is considered HIGH.
  • We can wait for the input reading to register as HIGH instead of looking for absolute thresholds of an analog value.
  • For an ATMega328P the threshold is 0.6 x VCC or around 3V. This is equivalent to just over 610 on a 0 to 1023 scale of an equivalent analog reading.

Taking this into account and using largely the same ideas as before, I can reuse most of the code but with the following timing and threshold values instead:

  • Start scaling (the 0 point): 10
  • End scaling (the 1023 point): 350

The timer TICK is still 100uS and the “breakout” point is still 1000.

When it comes to reading the digital INPUT, I’m using PORT IO once again for speed and expediency.

for (int i=0; i<4; i++) {
if ((PINC & (1<<i)) == 0) {
// Still not HIGH yet
}
}

Here is the complete, now greatly simplified, basic code:

#include <TimerOne.h>

#define RAW_START 10
#define RAW_END 350
#define RAW_BREAK 1000
#define RAW_TICK 100

unsigned padState;
unsigned padCount[4];
unsigned atariValue[4];

void atariAnalogSetup() {
Timer1.initialize(RAW_TICK);
Timer1.attachInterrupt(atariAnalogScan);
padState = 0;
}

void atariAnalogScan (void) {
if (padState == 0) {
DDRC = DDRC | 0x0F; // A0-A3 set to OUTPUT
PORTC = PORTC & ~(0x0F); // A0-A3 set to LOW (0)
padState++;
} else if (padState == 1) {
DDRC = DDRC & ~(0x0F); // A0-A3 set to INPUT
for (int i=0; i<4; i++) {
padCount[i] = 0;
}
padState++;
} else if (padState > RAW_BREAK) {
for (int i=0; i<4; i++) {
atariValue[i] = 1023 - map(constrain(padCount[i],RAW_START,RAW_END),RAW_START,RAW_END,0,1023);
}
padState = 0;
} else {
for (int i=0; i<4; i++) {
if ((PINC & (1<<i)) == 0) {
padCount[i]++;
}
}
padState++;
}
}

int atariAnalogRead (int pin) {
return atariValue[pin-A0];
}

void setup() {
Serial.begin(9600);
atariAnalogSetup();
}

void loop() {
Serial.print(padState);
Serial.print("\t[ ");
for (int i=0; i<4; i++) {
Serial.print(atariAnalogRead(A0+i));
Serial.print("\t");
Serial.print(padCount[i]);
Serial.print("\t][ ");
}
Serial.print("\n");
}

Closing Thoughts

Sometimes one really can’t see the “wood for the trees” and this was one of those occasions. I was so took up with thinking about how a modern system might think about a problem without thinking about the original reason for the particular solution.

It makes so much more sense thinking about it in these terms now. All it took was an observation from another, namely:

“So I know the RC timer is the classic way to sense analog paddles but they also didn’t have cheap ADCs back then.”

Many thanks “Chip” for that observation 🙂

Kevin

#arduinoUno #atari #atari2600 #include #potentiometer #TICKs

Atari 2600 Controller Shield PCB Revisited – Part 2

This has another look at my updated Atari 2600 Controller Shield PCB in order to attempt to read all four paddle controllers a bit more accurately and efficiently. Warning! I strongly recommend usi…

Simple DIY Electronic Music Projects