Saturday, 6 February 2021

eLK Elektroniks - building some ELMYRAs

 Excellent times building the Elmyras.
This is a complete synthesizer from Neutral Labs 
It's great for drones, and doubles as an effects processor.
 
Thanks to Ed for hosting the workshop.
 
The Elmyra was inspired by the Soma Lyra-8. 
Unlike the Lyra, the Elmyra has a filter and can be set so that the three oscillators are always tuned to a scale
 
Very easy build.
All parts supplied.
Its an excellent way to learn electronics.


 i'LL post some build notes soon.


Whether you build or purchase it, you may be interested in the PDF manual:





 
The next meeting is scheduled for the 20th March, in Wollongong.
Check the Elk Elektroniks facebook page for details and updates.
 
 

Friday, 5 February 2021

i2c LCD & encoder - scrollable menu

I've been searching for a way to build arduino menus
They are a common feature in many synths.
 

 A huge thank you to Curious Scientist for this navigation menu post

Hopefully, I'll be able to incorporate some of these ideas into future projects. 


 I didn't have a KY-040 rotary encoder on hand so had to make do with a "naked one"

The KY-040 has a breakout board which adds a Vcc pin
The  virgin encoder doesn't have this.
 
It has 5 pins:
1. CLK - Clock (Out B)
2. DT - data (Out A)
3. SW - switch (when we press the shaft, the switch connects to GND. Otherwise it is floating.)
4. GND
5. GND
 

You most often will find encoders without the breakout board.
 
They still have 5 pins.
Here there are two GNDs
There is no Vcc
 
 
 
 
 
 
The bare Rotary Encoder is connected to the following Arduino Uno pins
//      o CLK (out B) --> Pin 2
//      o DT  (Out A) --> Pin 4
//      o SW  --> Pin 3
//      o GND both  --> GND on arduino/breadboard
 
I used tinkercad to make the wiring diagram
 
LEDs
short legs - cathode to gnd (connects to 220 ohm resistors )
Anode - to digital pins 
Normally, I connect the anode to the digital pins via resistors, and 
the cathode goes in straight to gnd, however this other way seems to work fine too.


ground it well.

 
 
 // *********************************************
//16x2 LCD
#include <LiquidCrystal_I2C.h> //SDA = A4, SCL = A5
LiquidCrystal_I2C lcd(0x3F, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);


//Defining pins for rotary encoder
const int RotaryCLK = 2; //CLK pin on the rotary encoder
const int RotaryDT = 4; //DT pin on the rotary encoder
const int RotarySW = 3; //SW pin on the rotary encoder (Button function)

//Defining variables for rotary encoder and button
int ButtonCounter = 0; //counts the button clicks
int RotateCounter = 0; //counts the rotation clicks
bool rotated = true; //info of the rotation
bool ButtonPressed = false; //info of the button

//Statuses
int CLKNow;
int CLKPrevious;
int DTNow;
int DTPrevious;

// Timers
float TimeNow1;
float TimeNow2;

//LED things
//digital pins
const int whiteLED = 8;
const int blueLED = 9;
const int greenLED = 10;
const int yellowLED = 11;
const int redLED = 12;
//statuses (1/true: ON, 0/false: OFF)
bool whiteLEDStatus = false;
bool blueLEDStatus = false;
bool greenLEDStatus = false;
bool yellowLEDStatus = false;
bool redLEDStatus = false;
//------------------------------

//Drawing of the LCD layout
//W  B  G  Y  R   CLK
//0  0  0  0  0    1


void setup()
{

    //Serial.begin(9600); //we don't use the serial in this example
 
  //------------------------------------------------------
  lcd.begin(16,2);                      // initialize the lcd   
  lcd.backlight();
  //------------------------------------------------------
  lcd.setCursor(0,0); //Defining position to write from first row, first column .
  lcd.print("W B G Y R  CLK");
  lcd.setCursor(0,1); //second line, 1st block
  lcd.print("0 0 0 0 0   0"); //You can write 16 Characters per line .
  delay(3000); //wait 3 sec
  //------------------------------------------------------
   //setting up pins  
   pinMode(2, INPUT_PULLUP);
   pinMode(3, INPUT_PULLUP);
   pinMode(4, INPUT_PULLUP);

   pinMode(whiteLED, OUTPUT); //white LED
   pinMode(blueLED, OUTPUT); //blue LED
   pinMode(greenLED, OUTPUT); //green LED
   pinMode(yellowLED, OUTPUT); //yellow LED
   pinMode(redLED, OUTPUT); //red LED
 
  //LOW pins = LEDs are off. (LED + is connected to the digital pin)
   digitalWrite(whiteLED, LOW);
   digitalWrite(blueLED, LOW);
   digitalWrite(greenLED, LOW);
   digitalWrite(yellowLED, LOW);
   digitalWrite(redLED, LOW);
   

  //Store states
  CLKPrevious = digitalRead(RotaryCLK);
  DTPrevious = digitalRead(RotaryDT);
    
  attachInterrupt(digitalPinToInterrupt(RotaryCLK), rotate, CHANGE);
  attachInterrupt(digitalPinToInterrupt(RotarySW), buttonPressed, FALLING); //either falling or rising but never "change".

  TimeNow1 = millis(); //Start timer 1  
}


void loop()
{
  printLCD();
  ButtonChecker();
}

void buttonPressed()
{  
  //This timer is a "software debounce". It is not the most effective solution, but it works
  TimeNow2 = millis();
  if(TimeNow2 - TimeNow1 > 500)
  {    
    ButtonPressed = true;    
  }
  TimeNow1 = millis();  //"reset" timer; the next 500 ms is counted from this moment
}

void rotate()
{
  CLKNow = digitalRead(RotaryCLK); //Read the state of the CLK pin

  // If last and current state of CLK are different, then a pulse occurred  
    if (CLKNow != CLKPrevious  && CLKNow == 1)
    {
    // If the DT state is different than the CLK state then
    // the encoder is rotating CCW so increase
      if (digitalRead(RotaryDT) != CLKNow)
      {        
      RotateCounter++;

      if(RotateCounter > 4)
      {
       RotateCounter = 0;
      }

      }
      else
      {        
      RotateCounter--;
            
      if(RotateCounter < 0)
      {
        RotateCounter = 4;  
      }   
        
      }       
    }   

  CLKPrevious = CLKNow;  // Store last CLK state
  rotated = true;
}


void printLCD()
{
    if(rotated == true) //refresh the CLK
    {
      lcd.setCursor(12,1);
      lcd.print(RotateCounter);
      rotated = false;
    }
    
}


void ButtonChecker() //this is basically the menu part. keep track of the buttonpressed and rotatecounter for navigation
{
  if(ButtonPressed == true)
  {
    switch(RotateCounter)
    {
      case 0:      
      if(whiteLEDStatus == false)
      {
        whiteLEDStatus = true;
        digitalWrite(whiteLED, HIGH); //white LED is turned ON         
      }
      else
      {
        whiteLEDStatus = false;
        digitalWrite(whiteLED, LOW); //white LED is turned OFF           
      }

      lcd.setCursor(0,1); // Defining positon to write from second row, first column .
      lcd.print(whiteLEDStatus);
      
      break;
      
      case 1:
      if(blueLEDStatus == false)
      {
        blueLEDStatus = true;
        digitalWrite(blueLED, HIGH);  
        
      }
      else
      {
        blueLEDStatus = false;
        digitalWrite(blueLED, LOW);          
      }

      lcd.setCursor(2,1); // Defining positon to write from second row, first column .
      lcd.print(blueLEDStatus);
      break;
      
      case 2:
      if(greenLEDStatus == false)
      {
        greenLEDStatus = true;
        digitalWrite(greenLED, HIGH);  
        
      }
      else
      {
        greenLEDStatus = false;
        digitalWrite(greenLED, LOW);          
      }

      lcd.setCursor(4,1); // Defining positon to write from second row, first column .
      lcd.print(greenLEDStatus);
      break;
      
      case 3:
      if(yellowLEDStatus == false)
      {
        yellowLEDStatus = true;
        digitalWrite(yellowLED, HIGH);          
      }
      else
      {
        yellowLEDStatus = false;
        digitalWrite(yellowLED, LOW);          
      }
      lcd.setCursor(6,1); // Defining positon to write from second row, first column .
      lcd.print(yellowLEDStatus);
      
      break;
      
      case 4:
      if(redLEDStatus == false)
      {
        redLEDStatus = true;
        digitalWrite(redLED, HIGH);  
        
      }
      else
      {
        redLEDStatus = false;
        digitalWrite(redLED, LOW);          
      }

      lcd.setCursor(8,1); // Defining positon to write from second row, first column .
      lcd.print(redLEDStatus);
      break;
    }    
  }  
  ButtonPressed = false; //reset this variable
}
 
//******************************


 Links
+https://www.youtube.com/watch?v=Q58mQFwWv7c 
https://www.youtube.com/watch?v=CnS0PuDJybA
+ https://www.youtube.com/watch?v=x2J4VAYQGh0


 ---------------------------------
-------------------------------------

Thursday, 4 February 2021

OLED displays - arduino

 Organic Light Emitting Diodes or OLEDs don't need backlights,
They contain a film of an organic compound that emits light in response to electric currents.
They also consume less energy than LCDs
I2C uses just 4 pins
(though some come with an extra reset pin).
 
This is a 0.96" OLED LCD Display Module IIC I2C Interface 128x64

 
 
PinWiring to Arduino Uno
Vin5V
GNDGND
SCLA5
SDAA4              
 
To control the OLED display you need the Wire.h , adafruit_SSD1306.h and the adafruit_GFX.h libraries.
The Wire.h library will be installed by default  


 
 
Functions that are useful with OLEDS
  • display.clearDisplay() – all pixels are off
  • display.drawPixel(x,y, color) – plot a pixel in the x,y coordinates
  • display.setTextSize(n) – set the font size, supports sizes from 1 to 8
  • display.setCursor(x,y) – set the coordinates to start writing text
  • display.print(“message”) – print the characters at location x,y
  • display.display() – call this method for the changes to make effect 

 OLEDs communicate with your Arduino via i2c.
+ LCD display i2c - part 1   
 
The I2C is a type of serial bus developed by Philips, which uses two bidirectional lines, called SDA (Serial Data Line) and SCL (Serial Clock Line).  

Data connects to A4
Clock connects to A5 (Uno)


If when you first power it up and nothing happens, try to use a program with a different resolution
 
The  0.96" OLED may be 128x64 or 128x32

Though I bought this OLED thinking it was a 126 x 64 pixel, it runs the ssd1306_128x32_i2c
code.


 
 
 
 
 
 
 
 
 
 
 
 
 
 

 
 
 //*********************************************************************
 Code 2 - featherwing - in the examples of the IDE
 
This is the splashscreen
 

//****************
 #include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

Adafruit_SSD1306 display = Adafruit_SSD1306(128, 32, &Wire);

// OLED FeatherWing buttons map to different pins depending on board:
#if defined(ESP8266)
  #define BUTTON_A  0
  #define BUTTON_B 16
  #define BUTTON_C  2
#elif defined(ESP32)
  #define BUTTON_A 15
  #define BUTTON_B 32
  #define BUTTON_C 14
#elif defined(ARDUINO_STM32_FEATHER)
  #define BUTTON_A PA15
  #define BUTTON_B PC7
  #define BUTTON_C PC5
#elif defined(TEENSYDUINO)
  #define BUTTON_A  4
  #define BUTTON_B  3
  #define BUTTON_C  8
#elif defined(ARDUINO_FEATHER52832)
  #define BUTTON_A 31
  #define BUTTON_B 30
  #define BUTTON_C 27
#else // 32u4, M0, M4, nrf52840 and 328p
  #define BUTTON_A  9
  #define BUTTON_B  6
  #define BUTTON_C  5
#endif

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

  Serial.println("OLED FeatherWing test");
  // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // Address 0x3C for 128x32

  Serial.println("OLED begun");

  // Show image buffer on the display hardware.
  // Since the buffer is intialized with an Adafruit splashscreen
  // internally, this will display the splashscreen.
  display.display();
  delay(1000);

  // Clear the buffer.
  display.clearDisplay();
  display.display();

  Serial.println("IO test");

  pinMode(BUTTON_A, INPUT_PULLUP);
  pinMode(BUTTON_B, INPUT_PULLUP);
  pinMode(BUTTON_C, INPUT_PULLUP);

  // text display tests
  display.setTextSize(1);
  display.setTextColor(SSD1306_WHITE);
  display.setCursor(0,0);
  display.print("Connecting to SSID\n'adafruit':");
  display.print("connected!");
  display.println("IP: 10.0.1.23");
  display.println("Sending val #0");
  display.setCursor(0,0);
  display.display(); // actually display all of the above
}

void loop() {
  if(!digitalRead(BUTTON_A)) display.print("A");
  if(!digitalRead(BUTTON_B)) display.print("B");
  if(!digitalRead(BUTTON_C)) display.print("C");
  delay(10);
  yield();
  display.display();
}
//**********************
 
 
 
 Links
 
 
+ https://www.youtube.com/watch?v=HdgugXvqR3I 

-------------------------------------------------------------------------------------------

 ---------------------------------
-------------------------------------

Wednesday, 3 February 2021

NLC Dispersion Delay - part two.

This is part 2 of the Dispersion delay.
 

 I first started building this in Feb , 2020.
Sorry for the delay. 2020 was a shit year.
Let hope '21 is better for everyone.
 
rECTIFIERS USED.
 
 
 This  is a bandpass filter module 
This module is based on ideas suggested by Lucas Abela.
The filters are in parallel and use vactrols to control delay (& I think cutoff frequency) ??


These are the light dependent resistors which I used.
GL5549
The type of LDR is impt.
It should have a dark resistance of at least 1M ohm.
I like a slow attack (or response time). 
VTL5C3s have a slope of 20, a dark resistance of 10M Ohms and a very slow response time.

  LDR type nr 5516.are good too.
 The 5516 gives about 50 Ohms at full brightness
 
 This module uses 9 vactrols.
You could just buy 9 of them from thonk or synthcube, but I decided to make my own.
In Andrews build notes he suggested red/green/orange/yellow LEDs
 

I chose orange for no better reason that I had a spare bag full of them that I probably wasn't going to need soon.
The colour of the LED will have a bearing on how the vactrol works.
So experimentation is in order.
 
I read somewhere, that yellow LEDs make the most efficient circuit.
 the best match is between green and green/yellow.  A blue LED is the worst possible choice.
Also remember that LED colours are normally not precise.
 
To get the best possible performance, the LED and LDR should have equal wavelengths.
This will require checking datasheets to find a good match. 
 

The yellow shrink wrap is to prevent shorts.
 

testing shrinkwrap first.
Double layer. 
You could use a white internal heatshrink to reflect as much light as possible back to the LDR
Of course if you have a 3D printer then make your own light tight boxes.
 
 

Im inserting the LED side in first.
remember that the short lead is the cathode. = K
 


These are the headers to join the 2 boards.

Jacks next.
All the pots are B100k

I'm surprised at just how well these vactrols work.


If anyone had tried making their own and experimented with different LEDs or LDRs do let me know.

 

---------------------------------------------------------------------------------------------------
Click here to return to the NLC Build Index:
http://djjondent.blogspot.com.au/2015/03/non-linear-circuits-ncl-index.html

Tuesday, 2 February 2021

Ringworld - Larry Niven

This is solid classic sci-fi.
Great world building.
It's part of a series.The " Known Space" series.
The books were written by American author Larry Niven.
 

The series is composed of five standalone science fiction novels.

Fate of Worlds is also a sequel to the four books of the Fleet of Worlds series, set in the same "Known Space" universe and all written by Niven and Edward M. Lerner:

“Ringworld” was written in Oct, 1970.
It follow the adventures of Louis Gridley Wu, who accepts the invitation to join a young woman and a couple of aliens on a journey to the mysterious Ringworld.

The Ringworld, is a giant object, 600 million miles in circumference, (1 million miles across),
 built around a star. It's a  megastructure, a marvel of engineering, consisting of a greater mass than Jupiter.
The ring has an atmosphere like Earth's and it rotates around the star to provide artificial gravity.
 A compromise between a Dyson Sphere and a planet ?
 
This is definitely a classic and I recommend that anyone interested in Sci-Fi  read it.
However, the story telling is a bit slow and tedious, so be warned. I did struggle with myself to finish it. I think the book may have won it's Hugo award on its concept which is pretty cool for the time.

These travelers become stranded on the hostile ring, and must find a way to get home.
 
Luis Wu, must outplay the murderous Kzin, & conquer the traps the ringworld.
It turns out that the Puppeteers have been manipulating humans for their "luck gene"
and the Kzin for aggression.

It's I guess why they are called puppeteers.
Getting towards the end of the book I realised that the whole novel really is about the female character Teela. Was the entire mission a result of her luck gene? In the end, it unites her with her true love.
It's interesting that luck is considered a genetic trait, that can be strengthened by selective breeding.






--------------------------------------------

sci Fi Index

----------------------------------------------

Monday, 1 February 2021

Eurorack Jam at Elk Elektronik

..

Nice one Ed.

The system uses many NLC modules. Esp like the Null-A
NULL-A Build notes

Nelson Falls - Mt Field - Tasmania

 Located in the Franklin-Gordon Wild Rivers National Park.
 


West Coast region of Tasmania
 




The landscape ranges from eucalyptus temperate rainforest to alpine moorland, rising to 1,434 metres at the summit of Mount Field .
Mount Field National Park was the first national park created in Tasmania.
Established in 1916.  It's 64 km northwest of Hobart.
 It's part of the homelands of the Big River nation of Tasmanian Aborigines.
 


The largest trees here were growing when Abel Tasman first sighted Tasmania in 1642.
Many are over 100m high.