Input and output circuits
By Amanda Ghassaei
http://www.amandaghassaei.com/arduinodsp.html
Transmit AM audio on 727 KHz. using a voltage divider and an Arduino.
By Markus Gritsch
Note: with the actual circuit the signal is closer to 760 KHz.
Samples incoming audio at 34 KHz. and rebroadcasts as RF using the Arduino clock.
This is a simplification of Markus’ original circuit. It eliminates the tuned output circuit. Probably at the expense of increased harmonic distortion.
The voltage divider is uses 2 47K Ohm resistors and a 1 uF electrolytic capacitor. It is the input half of the original circuit.
http://dangerousprototypes.com/forum/viewtopic.php?f=56&t=2892#p28410
(I substituted 2 100 K Ohm resistors in parallel for each of the 47 K’s.)
A voltage divider is useful as a general purpose coupler, for sampling analog signals using Arduino PWM input.
The Arduino sketch is Markus’ original – reprinted here:
(note) Local file is AM_audio_transmitter.
// Simple AM Radio Signal Generator :: Markus Gritsch // http://www.youtube.com/watch?v=y1EKyQrFJ−o // // /|\ +5V ANT // | \ | / // | −−−−−−−−−−−−−−−− \|/ // | | R1 | Arduino 16 MHz | C2 | // | | 47k | | || | about // audio C1 | | | TIMER_PIN >−−−−−||−−−−−+ 40Vpp // input || | | | || | // o−−−−−||−−−−−+−−−−−−−> INPUT_PIN | 1nF | // +|| | | | ) // 1uF | | R2 | ATmega328P | ) L1 // | | 47k −−−−−−−−−−−−−−−− fres = ) 47uH // fg < 7 Hz | | 734 kHz ) // | | // | | // −−− GND −−− GND // // fg = 1 / ( 2 * pi * ( R1 || R2 ) * C1 ) < 7 Hz // fres = 1 / ( 2 * pi * sqrt( L1 * C2 ) ) = 734 kHz #define INPUT_PIN 0 // ADC input pin #define TIMER_PIN 3 // PWM output pin, OC2B (PD3) #define DEBUG_PIN 2 // to measure the sampling frequency #define LED_PIN 13 // displays input overdrive #define SHIFT_BY 3 // 2 ... 7 input attenuator #define TIMER_TOP 20 // determines the carrier frequency #define A_MAX TIMER_TOP / 4 void setup() { pinMode( DEBUG_PIN, OUTPUT ); pinMode( TIMER_PIN, OUTPUT ); pinMode( LED_PIN, OUTPUT ); // set ADC prescaler to 16 to decrease conversion time (0b100) ADCSRA = ( ADCSRA | _BV( ADPS2 ) ) & ~( _BV( ADPS1 ) | _BV( ADPS0 ) ); // non−inverting; fast PWM with TOP; no prescaling TCCR2A = 0b10100011; // COM2A1 COM2A0 COM2B1 COM2B0 − − WGM21 WGM20 TCCR2B = 0b00001001; // FOC2A FOC2B − − WGM22 CS22 CS21 CS20 // 16E6 / ( OCR2A + 1 ) = 762 kHz @ TIMER_TOP = 20 OCR2A = TIMER_TOP; // = 727 kHz @ TIMER_TOP = 21 OCR2B = TIMER_TOP / 2; // maximum carrier amplitude at 50% duty cycle } void loop() { // about 34 kHz sampling frequency digitalWrite( DEBUG_PIN, HIGH ); int8_t value = (analogRead( INPUT_PIN ) >> SHIFT_BY ) - (1 << (9 - SHIFT_BY )); digitalWrite( DEBUG_PIN, LOW ); // clipping if( value < -A_MAX) { value = -A_MAX; digitalWrite( LED_PIN, HIGH ); } else if ( value > A_MAX ) { value = A_MAX; digitalWrite( LED_PIN, HIGH ); } else { digitalWrite( LED_PIN, LOW ); } OCR2B = A_MAX + value; }
Transmit FM audio on 434.65 Mhz. by substituting a Radiometrix NTX2 for a crystal oscillator in this circuit:
http://scitoys.com/scitoys/scitoys/radio/am_transmitter.html
Radiometrix: http://www.radiometrix.com/content/ntx2
NTX2 datasheet: http://www.radiometrix.com/files/additional/ntx2nrx2.pdf
On the NTX2, the connections are:
A voltage divider input coupler will also work. See this post for a simple circuit: https://reactivemusic.net/?p=12263
A circuit from the UK High Altitude Balloon sight, that sends RTTY, from Arduino using the Radiometrix NTX2 transmitter on 434.650 Mhz.
http://ukhas.org.uk/guides:linkingarduinotontx2#where_to_buy_the_ntx2
substituted 2 100k resistors in parallel for the 47k connected to TX output in the circuit
We used rtl-sdr with Max as the receiver, in SSB mode, sending audio via Soundcloud to dl-fldigi to decode the RTTY. The params that worked:
Unfortunately there was no way to hear the signal while decoding because dl-fldigi doesn’t feed through the input audio. A workaround is to run Audacity in the background. In audacity:
An updated version of the system described above.
This circuit features no additional components. Just the NTX2 and Arduino. The voltages are generated using PWM (pulse width modulation).
Described in a 3 part series.
by Anthony Stirk at ava.upuaut.net
The first example generates a carrier shift of 310 Hz. It took several minutes for the transmit frequency to stop drifting. The AFC setting in dl-fldigi helps to keep things locked in – as long as their is a constant carrier.
Reducing the filter bandwidth to less than 150 Hz helps, due to the narrow carrier shift.
Requires a 175 ohm resistor for precise timing. Didn’t have one, so I just ran the sketch without decoding. Here’s what it sounds like:
Make music from the motion of stock prices.
This program gathers stock prices into a database. It generates Midi data – mapping price to pitch, and mapping trading volume to velocity and rhythmic density. It uses ancient Web technology: HTML/javascript front-end with a php back-end accessing a mysql database.
Case study: http://zproject.wikispaces.com/stock+market+music
To run this project, you will need a server (preferably linux) with the following capabilities:
All of this is pretty standard – so I won’t talk about it here. I am running it on Ubuntu Linux. There are many other ways to get the project working, by using the layout described here.
https://github.com/tkzic/internet-sensors
folder: stock-market
stock_market_music.maxpat
The selectstock3.php program harvests stock quote data and stores it in a mysql database.
The database name is: stocks – table is: quotes
Table structure:
The table is basic flat representation of a stock quote, indexed by the ticker symbol. It contains price, volume, high/low/change, timestamp, etc., For our purposes, the price, volume and timestamp are essentially all we need.
SQL to create the table:
CREATE TABLE `stocks`.`quotes` ( `ticker` varchar( 12 ) NOT NULL , `price` decimal( 10, 2 ) NOT NULL , `qtime` datetime NOT NULL , `pchange` decimal( 10, 2 ) NOT NULL , `popen` decimal( 10, 2 ) NOT NULL , `phigh` decimal( 10, 2 ) NOT NULL , `plow` decimal( 10, 2 ) NOT NULL , `volume` int( 11 ) NOT NULL , `ttime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP , `id` int( 11 ) NOT NULL AUTO_INCREMENT , `spare` varchar( 30 ) DEFAULT NULL , UNIQUE KEY `id` ( `id` ) , KEY `ticker` ( `ticker` ) ) ENGINE = MyISAM DEFAULT CHARSET = latin1 COMMENT = 'stock quote transactions';
The webpage control program allows you to select stocks by ticker symbol, and get either one quote or get quotes at regular time interval. Each quote is inserted into the stock table for later retrieval and analysis.
The web front end is quirky so I will describe it in terms of how you might typically use it:
To look at historical trends, you would need access to historical stock data. To use it as a tool for short term analysis, you would need access to real-time quote data in an API. At the time, both of these cost money.
However, it doesn’t cost money to get recent quotes from Yahoo throughout the day and store them in a database – so that’s the approach I took.
If I were to do this project today, I’d look for a free online source of historical data, in machine-readable form – because the historical data provides the most interesting and organic sounds when converted into music. The instant high speeding trading data would probably make interesting sounds as well, but you still need to pay for the data.
[Note: xively.com is gone. This system doesn’t work. Post is here for historical reasons only]
Bi-directional communication from Arduino to a xively.com feed using an ethernet shield.
[wpdm_file id=18 title=”true” ]
Copy the xively_test1/ folder to Documents/Arduino. This puts it in the Arduino sketchbook.
Notes on installing xively/cosm/pachube libraries for arduino: https://reactivemusic.net/?p=4900
Instructions
/* 5/20/2014 - Arduino/xively feed interaction
Uses Ethernet Shield and and LED connected between pin D5 and ground
Sends a random value to a xively.com feed every minute The LED lights up during data transmissions
demonstrates:
HTTP PUT - send data to xiveyly feed and store HTTP GET - read xively feed value
*/
#include <SPI.h> #include <Ethernet.h> #include <HttpClient.h> #include <Cosm.h>
int ledPin = 5;
int upCount = 0; // counters for number of times going up and down
#define API_KEY "96PqSh4rj7HzNif3WtTpN7GjX96SAKxrWms3SUhwaDFGUT0g" // your Cosm API key #define FEED_ID 98281 // your Cosm feed ID
// MAC address for your Ethernet shield byte mac[] = { 0x90, 0xA2, 0xDA, 0x0D, 0x0B, 0xCE };
// note that pins 0 and 1 are used by the Ethernet shield
unsigned long lastConnectionTime = 0; // last time we connected to Cosm const unsigned long connectionInterval = 60000; // delay between connecting to Cosm in milliseconds
// Initialize the Cosm library
// Define the string for our datastream ID char sensorId[] = "count";
CosmDatastream datastreams[] = { CosmDatastream(sensorId, strlen(sensorId), DATASTREAM_FLOAT), };
// Wrap the datastream into a feed CosmFeed feed(FEED_ID, datastreams, 1 /* number of datastreams */);
EthernetClient client; CosmClient cosmclient(client);
void setup() { // initialize the detector pins pinMode(ledPin, OUTPUT ); // internet transmitting indicator // start the Monitor (console) serial port Serial.begin(9600);
// display happy messages Serial.println("Xively test"); Serial.println("==========================");
// Keep trying to initialize the Internet connection // Note - we should eventually timeout of this and just run the stairs independently Serial.println("Initializing network"); while (Ethernet.begin(mac) != 1) { Serial.println("Error getting IP address via DHCP, trying again..."); delay(15000); }
Serial.println("Network initialized"); Serial.println(); // print your local IP address: Serial.print("Arduino IP address: "); for (byte thisByte = 0; thisByte < 4; thisByte++) { // print the value of each byte of the IP address: Serial.print(Ethernet.localIP()[thisByte], DEC); Serial.print("."); } Serial.println(); Serial.println(); } // end of setup function
//////////////////////////// control loop ///////////////////////////
void loop() { // main program loop ////////////////////////////// Internet sending/receiving code //////////////////////////////// if (millis() - lastConnectionTime > connectionInterval) { // uncomment this to just send a random value... upCount = random(256); digitalWrite(ledPin, HIGH ); // turn on transmitter light sendData(upCount); // read the datastream back from Cosm - comment out to save time getData(); digitalWrite(ledPin, LOW ); // update connection time so we wait before connecting again lastConnectionTime = millis(); } ///////////////////// end of internet send/receive code ///////////////// } // end of main loop code
/////////////////// additional functions ////////////////////////// ////////////////////////////////////////////////////////////////////
// send the supplied value to Cosm, printing some debug information as we go void sendData(int sensorValue) { datastreams[0].setFloat(sensorValue);
Serial.print("Read sensor value "); Serial.println(datastreams[0].getFloat());
Serial.println("Uploading to Cosm"); int ret = cosmclient.put(feed, API_KEY); Serial.print("PUT return code: "); Serial.println(ret);
Serial.println(); }
// get the value of the datastream from Cosm, printing out the value we received void getData() { Serial.println("Reading data from Cosm");
int ret = cosmclient.get(feed, API_KEY); Serial.print("GET return code: "); Serial.println(ret);
if (ret > 0) { Serial.print("Datastream is: "); Serial.println(feed[0]);
Serial.print("Sensor value is: "); Serial.println(feed[0].getFloat()); }
Serial.println(); }
“Turns any hard surface into an interface”
from creativeapplications.net
Control Max with your phone
https://github.com/tkzic/max-projects
folder: accelerometer-osc
patch: osc-accel-test.maxpat