online now

We have 69 guests and no members online


Welcome, Guest
Username: Password: Remember me
  • Page:
  • 1

TOPIC: need help with programming--noob

need help with programming--noob 1 year 10 months ago #870

okay ive been literally trying to figure this out for hours and hours on end, and i have gotten absolutely nowhere. my coding knowledge is very limited, so bear with me. The project I have built is a frameless laser harp, via this setup makezine.com/projects/build-two-octave-laser-harp/

Now, what I am trying so desperately to do is simply change the way the notes sound. I thought I could just replace poly with preset, and replace waveform with one of the presets and tweak fromthere. that obviusly doesnt work, setnote doesnt work with preset. So im thinkinh punch through synth to alter the sound? I really have no clue whatsoever where to begin, everytime i chage one thing, 20 more errors pop up and then 20 more for each of those. im ready to throw my laptop at the wall lol. in addition i couldt figure out/have time for soundgin, and tweaker isnt workng (im on linux) it sees the port, i click it, and it closes down. so ive pretty much had it with this thing and wish i had gone wth a midi out on my laser harp as opposed to this ginsing conundrum. here is the original code i am working off of:
#include <GinSing.h>
#include <GinSingDefs.h>
#include <GinSingMaster.h>
#include <GinSingPoly.h>
#include <GinSingPreset.h>
#include <GinSingSerial.h>
#include <GinSingSerialMacros.h>
#include <GinSingSynth.h>
#include <GinSingVoice.h>

#include <Wire.h>
#include <GinSing.h>
#include <Adafruit_MotorShield.h>
#include "utility/Adafruit_PWMServoDriver.h"

#include "HarpNoteChoice.h"
#include "HarpNoteDetection.h"

//When debugging I wanted more information. So ... set this boolean to true
//to get more stuff printed to the console. When it's true the console dumps LOTS of
//great stuff - but the code CRAWLS and the laser harp isn't great.
const boolean debug = false;

// Create the motor shield object with the default I2C address
Adafruit_MotorShield AFMS = Adafruit_MotorShield();
// Or, create it with a different I2C address (say for stacking)
// Adafruit_MotorShield AFMS = Adafruit_MotorShield(0x61); 

// Connect a stepper motor with 200 steps per revolution (1.8 degree)
// to motor port #2 (M3 and M4)
Adafruit_StepperMotor *myMotor = AFMS.getStepper(200, 2);

GinSing  GS;
#define rcvPin  4  // this is the pin used for receiving    ( can be either 4 or 12 )
#define sndPin  3  // this is the pin used for transmitting ( can be either 3 or 11 ) 
#define ovfPin  2  // this is the pin used for overflow control ( can be either 2 or 10 )
GinSingPoly * poly;

#define GINSING0 0                                      
#define GINSING1 1   

const int lightSensorPin = 0;

const int stepSize = 1;
const int delayBetweenSteps = 15;
const int numberNotes = 7;

GSNote ginsingNotes[numberNotes + 1];

const int buttonApin = 9;
const int buttonBpin = 8;

HarpNoteChoice harpNoteChoice;
HarpNoteDetection harpNoteDetector;

boolean pluckedNotes[numberNotes];
int reflectedLightValues[numberNotes];

void setup()

	//For the light sensor

	pinMode(buttonApin, INPUT_PULLUP);
	pinMode(buttonBpin, INPUT_PULLUP);

	AFMS.begin();  // create with the default frequency 1.6KHz

	//Get some initial values for each light string
	for (int i = 0; i < numberNotes; i++) {
		reflectedLightValues[i] = analogRead(lightSensorPin);
		pluckedNotes[i] = false;


//This is the code required to get GinSing ready to go.
void setupGinSing() {
	GS.begin(rcvPin, sndPin, ovfPin);               // start the device (required) and enter preset mode
	//For preset mode - change this when going to poly mode
	poly = GS.getPoly();
	poly->begin();                                    // enter presetmode

	poly->setWaveform(GINSING0, SAWTOOTH);
	poly->setWaveform(GINSING1, SAWTOOTH);


//These are the notes I want to play with GinSing.
void setupGinsingNotes() {
	ginsingNotes[0] = C_4;
	ginsingNotes[1] = D_4;
	ginsingNotes[2] = E_4;
	ginsingNotes[3] = F_4;
	ginsingNotes[4] = G_4;
	ginsingNotes[5] = A_4;
	ginsingNotes[6] = B_4;

//This code is used to take the sonar reading and convert
//that into something to change the GinSing note being played.
int findMultiplier(int height) {
	Over 170 = nothing
	140 = high           80 - 5
	125 = normal  64 - 4
	110 = low            48 - 3
	92 = very low       32 - 2
	74 = lower          16 - 1
	62 bottom out
	if (height > 135) return 5;
	if (height > 119) return 4;
	if (height > 100) return 3;
	if (height > 80) return 2;
	//My speaker gets weird at the low values. So I commented that one out.
//	if (height > 65) return 1;
	return 0;

//Read the sonar unit and figure out if the
//notes should move up or down 
void checkSonar() {
	int height = analogRead(1);

	if (debug) {

	if (height > 170) {
	int multiplier = findMultiplier(height);
	int baseValue = 16 * multiplier;

	ginsingNotes[0] = (GSNote)baseValue;
	ginsingNotes[1] = (GSNote)(baseValue + 1);
	ginsingNotes[2] = (GSNote)(baseValue + 2);
	ginsingNotes[3] = (GSNote)(baseValue + 3);
	ginsingNotes[4] = (GSNote)(baseValue + 4);
	ginsingNotes[5] = (GSNote)(baseValue + 5);
	ginsingNotes[6] = (GSNote)(baseValue + 6);

//These two are the notes that Ginsing is currently playing.
int ginsingNote0 = -1;
int ginsingNote1 = -1;

//FirstNote and SecondNote are the notes we want to be playing.
void playNote(int firstNote, int secondNote) {

	if (debug) {
		Serial.print("Playing notes ");
		Serial.print(" and ");

	//Pick the notes to be played and which channel to play them on
	harpNoteChoice.pickNotes(ginsingNote0, ginsingNote1, firstNote, secondNote);

	if (ginsingNote0 == -1) {
	else {
		poly->setNote(GINSING0, ginsingNotes[ginsingNote0]);

	if (ginsingNote1 == -1) {
	else {
		poly->setNote(GINSING1, ginsingNotes[ginsingNote1]);


//Move the motor one step. Sleep, then take a light reading. The sleep
//gives the sensor time to actually report the new reading.
int stepTheMotorAndGetLightReading(int directionToStep) {
	myMotor->step(stepSize, directionToStep, DOUBLE);
	int currentLightReading = analogRead(lightSensorPin);
	return currentLightReading;

//Is debug on? If so print some data.
void checkNotes(int reflectedLightValues[], boolean pluckedNotes[]) {
	if (debug) {
		for (int i = 0; i < numberNotes; i++) {
			Serial.print(" - ");

	//So ... are any light readings different from any others?
	//To find the anomaly, see how different each string is to every other string.
	//One or two strings should stand out. Those are the plucked strings.
	harpNoteDetector.checkNotes(reflectedLightValues, pluckedNotes);

	//So what strings are plucked? Note that if more than two are plucked,
	//that counts as an error ... if that's the case, just keep playing the current notes
	//and hope the player gets his act straight.
	int firstNote = -1;
	int secondNote = -1;
	if (harpNoteDetector.getNotes(firstNote, secondNote, pluckedNotes)) {
		if (debug) {  
			if (firstNote >= 0) {
				Serial.print("==============PLUCKED 1: ");
			if (secondNote >= 0) {
				Serial.print("==============PLUCKED 2: ");
		playNote(firstNote, secondNote);
	else if (debug) {
		Serial.println("getNotes returned false - more than three notes were counted as plucked.");

//Is a button pressed? If so move the motor a bit. This lets the user adjust the laser fan so it's pointing upwards properly.
void checkButtons() {
	if (digitalRead(buttonApin) == LOW) {
		myMotor->step(stepSize, BACKWARD, DOUBLE);

	if (digitalRead(buttonBpin) == LOW) {
		myMotor->step(stepSize, FORWARD, DOUBLE);

void loop()

	//There must be at least a handful notes for the code below to work right.
	if (numberNotes < 5) {

	//Run the laser forward, read all values, and see what is there. Note that this pretty much uses one
	//less note than requested - but the START position counts as a spot. So moving it numberNotes makes that many
	//strings plus the start string.

	//It's already read the zero item. So read array items 1 through 7.
	for (int i = 1; i < numberNotes; i++) {
  		reflectedLightValues[i] = stepTheMotorAndGetLightReading(FORWARD);
		checkNotes(reflectedLightValues, pluckedNotes);


	//It just read item 7. So going backwards, read items 6 through zero.
	for (int i = numberNotes - 2; i >= 0; i--) {
		reflectedLightValues[i] = stepTheMotorAndGetLightReading(BACKWARD);
		checkNotes(reflectedLightValues, pluckedNotes);



oh and i also cant figure out hpw tp modify the code to accomodate my hypersonic sensor, which has 4 pins like this one playground.arduino.cc/Main/UltrasonicSensor instead of 3 pins, and uses NewPing. I bit off way more than i could chew but its a freakin laser harp and its so bad ass!
The administrator has disabled public write access.

need help with programming--noob 1 year 10 months ago #871

If I read your post correctly, the issue you are dealing with is changing the way the notes sound, but otherwise it is working. If this is the case, let me explain briefly how poly mode and synth mode differ that might clear up the situation a bit.

The GinSing has 6 DCOs (digitally controlled oscillators), that are simple waveform generators - each of which can take on wave shapes of square, ramp, triangle, sine, pulse, and noise. In synth mode, you can patch these DCOs together to create complex sounds using amplitude modulation, frequency modulation, pitch ramping, and so on. Each DCO also has its own ADSR envelope generator. The complexity of sound comes from how these are wired together, and how you change the parameters. The entire voice synthesis is performed not by recorded voice samples, but connecting and manipulating the settings to simulation human voice. In Synth mode, you have full access to configure these in a huge variety of ways, and generally you want to generate one complex monophonic sound.

Poly mode is a simplification of Synth mode for musical applications. Poly mode configures the DCOs to be exact copies of each other so that you can play up to 6 note simultaneously. Each voice is a single simple DCO patched to the mixer directly, and they share the same ADSR. The way you get tonal variation in poly mode is to pick the basic wave shape, and then use the ADSR to add volume characteristics to simulate real world instruments. In this sense the tonal qualities are very simple, but there is still a good range of variation. It is not, however a complex instrument synthesizer that you would get from a MIDI style device. Conceptually Poly mode is a configuration of Synth mode.

Finally, Preset mode is a pre-configured selectable set of sounds the set up the synthesizer to give you a starting point, and are more like sound effects than anything else. You can load a preset in preset mode, and then switch to synth mode to tweak the setup if you like, but in general they are not meant for musical applications.

So, what that means for you I think is that you probably might want to keep poly mode if you want polyphonic capability (up to six notes at once) and play with the wave shape and ADSR. If you only want a single note at a time, you can use synth mode to set up more complex tonal qualities, but you'll be controlling the DCO frequencies, patching, and ADSR individually (or together depending on how you configure the voices). Hopefully that will help with the understanding - once you pick a certain mode, we can discuss further the capabilities to improve the quality.
The administrator has disabled public write access.
The following user(s) said Thank You: Skinnykinney

need help with programming--noob 1 year 10 months ago #872

That definitely clears up a bit more on what each mode is meant for/capable of thank you. So I should keep poly mode for having my notes for each string, then use synth mode to punch through to change the effect/sound of my notes? I basically want to now just make my "instrument" sound cooler and less like a child's keyboard lol. So where /how would i set up the synth code to change that? In the beginning?
The administrator has disabled public write access.

need help with programming--noob 1 year 10 months ago #874

Generally speaking switching from poly mode to synth mode would result in a pretty abrupt change. If you reset between modes, you would be muting all the voices, and if you did not you would be switching settings with different starting points depending on what parameters were set in voice mode when the switch happened. Synth mode is very rich, and pretty complicated to fully understand - I would recommend experimenting with Tweaker if you wanted to go that route.

IMHO you can get a pretty interesting range of sounds from whistles, to organs, and so forth by combining voices or using the noise/bend functions. If you are willing to eat some polyphony for example, you can combine a few voices together to harmonize, or octavize. I have attached a bit of code that might get you thinking in this direction from a project I did a while ago called the airmonica. This code is not fully documented, but might give you some ideas.
The administrator has disabled public write access.
The following user(s) said Thank You: Skinnykinney

need help with programming--noob 1 year 10 months ago #875

thank you soo much that actually helps a lot, like i said im not too knowledgeable wuth programming/code but seeing examples helps a TON, aside from memorizing the different terms/code seeing how its set up helps, the reference and programing guides are good but not nearly as in depth as id like, but again im new to arduino and ginsing. ill try playing with it some more and see what i come up with, hopefully i can get tweaker to work on my linux machine
The administrator has disabled public write access.

need help with programming--noob 1 year 10 months ago #876

Great! Please feel free to continue the conversation as you experiment, and I look forward to seeing your project posted on our front page some day!
The administrator has disabled public write access.

need help with programming--noob 1 year 10 months ago #877

A quick q, was the arpreggiator.h referenced in your code somethng you made yourself or is it included in arduino libraries? Still learning sorry if a redundant question
The administrator has disabled public write access.

need help with programming--noob 1 year 9 months ago #878

Sorry for the delay in responding. Yes, it was something I made myself. I think the full source is available from the intractable, but if you can't find it there let me know and I'll post it here.
The administrator has disabled public write access.
  • Page:
  • 1
Time to create page: 0.403 seconds