BabyGnusbuino code examples: Difference between revisions

From SGMK-SSAM-WIKI
Jump to navigation Jump to search
(Created page with "=== setup() === best to set the pins used for programming via USB again as outputs and low, before starting your program <syntaxhighlight lang="c"> void setup() { // Set pins ...")
 
Line 171: Line 171:
<syntaxhighlight lang="c">
<syntaxhighlight lang="c">


/***
// based largely on Atmel's AVR138: Low-Jitter Multi-Channel Software PWM Application Note:
babygnusbuino blend
// http://www.atmel.com/dyn/resources/prod_documents/doc8020.pdf
***/
 
#include <avr/io.h>
#include <avr/io.h>
#include <avr/interrupt.h>  
#include <util/delay.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#define CHMAX 3 // maximum number of PWM channels
#define PWMDEFAULT 0x00 // default PWM value at start up for all channels
#define RED_CLEAR (pinlevelB &= ~(1 << RED)) // map RED to PB4
#define GREEN_CLEAR (pinlevelB &= ~(1 << GREEN)) // map GREEN to PB3
#define BLUE_CLEAR (pinlevelB &= ~(1 << BLUE)) // map BLUE to PB0
//! Set bits corresponding to pin usage above
#define PORTB_MASK  (1 << PB4 | 1 << PB3| 1 << PB0)
#define set(x) |= (1<<x)
#define clr(x) &=~(1<<x)
#define inv(x) ^=(1<<x)
#define RED PB4
#define GREEN PB3
#define BLUE PB0
#define LED_PORT PORTB
#define LED_DDR DDRB


int LED0 = 0; // Blue
// function prototypes
int LED1 = 1; // Red
void delay_ms(uint16_t ms);
int LED2 = 2; // Green
void init();
void blend(int r, int g, int b, int da);  
// global variables
unsigned char compare[CHMAX];
volatile unsigned char compbuff[CHMAX];
unsigned long lfsr = 1;
unsigned char temp;


volatile unsigned char e = 0;
int main() {
volatile unsigned char BRGLed[3] = {0,0,0};
 
init();
void setup()
{
for (;;) { // forever
   randomSeed(analogRead(0));
    
lfsr = (lfsr >> 1) ^ (-(lfsr & 1u) & 0xd0000001u); // taps 32 31 29 1
   // Timer Init
temp = (unsigned char) lfsr; // take lowest eight bits
   cli();
temp = (unsigned char) (lfsr >> 24);
    
int r = temp & 0xff;
  TCCR0A = 0x00;
  TCCR0B = 0x01;
lfsr = (lfsr >> 1) ^ (-(lfsr & 1u) & 0xd0000001u); // taps 32 31 29 1
   TIMSK = (1 << TOIE1); // Overflow
temp = (unsigned char) lfsr; // take lowest eight bits
temp = (unsigned char) (lfsr >> 24);
int g = temp & 0xff;
lfsr = (lfsr >> 1) ^ (-(lfsr & 1u) & 0xd0000001u); // taps 32 31 29 1
temp = (unsigned char) lfsr; // take lowest eight bits
temp = (unsigned char) (lfsr >> 24);
int b = temp & 0xff;
for (int a = 0; a < 64; a++) {  
_delay_ms(20);
blend(r,g,b,a); // r g b alpha   
}
}
}
void delay_ms(uint16_t ms) {
   while (ms) {
    _delay_ms(1);
    ms--;
   }
}
void init(void) {
   // set the direction of the ports
   LED_DDR set(RED);
   LED_DDR set(GREEN);
   LED_DDR set(BLUE);
    
    
  unsigned char i, pwm;
  CLKPR = (1 << CLKPCE);        // enable clock prescaler update
  CLKPR = 0;                    // set clock to maximum (= crystal)
  pwm = PWMDEFAULT;
  // initialise all channels
  for(i=0 ; i<CHMAX ; i++) {
    compare[i] = pwm;          // set default PWM values
    compbuff[i] = pwm;          // set default PWM values
  }
  TIFR = (1 << TOV0);          // clear interrupt flag
  TIMSK = (1 << TOIE0);        // enable overflow interrupt
  TCCR0B = (1 << CS00);        // start timer, no prescale
   sei();
   sei();
 
  pinMode(LED0, OUTPUT);
  pinMode(LED1, OUTPUT);
  pinMode(LED2, OUTPUT);
}
}
 
void loop()
{
ISR (TIM0_OVF_vect) {
   int r = random(0,255);
   static unsigned char pinlevelB=PORTB_MASK;
   int g = random(0,220);
   static unsigned char softcount=0xFF;
   int b = random(0,220);
   PORTB = pinlevelB;           // update outputs
    
    
   for (int a = 0; a < 60; a++) {
   if(++softcount == 0){        // increment modulo 256 counter and update
     delay(8000);
                                // the compare values only when counter = 0.
     blend(r,g,b,a); // r g b alpha   
    compare[0] = compbuff[0];   // verbose code for speed
    compare[1] = compbuff[1];
     compare[2] = compbuff[2];
     pinlevelB = PORTB_MASK;     // set all port pins high
   }
   }
  // clear port pin on compare match (executed on next interrupt)
  if(compare[0] == softcount) RED_CLEAR;
  if(compare[1] == softcount) GREEN_CLEAR;
  if(compare[2] == softcount) BLUE_CLEAR;
}
}


Line 229: Line 306:
   int sa = 255 - da;
   int sa = 255 - da;
    
    
   int tb = (sa * BRGLed[0] + da * b) + 128;
   int tr = (sa * compbuff[0] + da * r) + 128;
   int tr = (sa * BRGLed[1] + da * r) + 128;
   int tg = (sa * compbuff[1] + da * g) + 128;
   int tg = (sa * BRGLed[2] + da * g) + 128;
   int tb = (sa * compbuff[2] + da * b) + 128;
    
    
   BRGLed[0] = ((tb>>8)+tb)>>8;
   compbuff[0] = ((tr>>8)+tr)>>8;
   BRGLed[1] = ((tr>>8)+tr)>>8;
   compbuff[1] = ((tg>>8)+tg)>>8;
   BRGLed[2] = ((tg>>8)+tg)>>8;
   compbuff[2] = ((tb>>8)+tb)>>8;
    
    
}
// Overflow routine for Timer 1
ISR(TIM1_OVF_vect) {
  if(e==255) {
    e=0;
    digitalWrite(LED0, HIGH);
    digitalWrite(LED1, HIGH);
    digitalWrite(LED2, HIGH);
    }
  if (BRGLed[0] == e) { 
    digitalWrite(LED0, LOW);
  }
  if (BRGLed[1] == e) { 
    digitalWrite(LED1, LOW);
  }
  if (BRGLed[2] == e) { 
    digitalWrite(LED2, LOW);
  }
  e++;
}
}


</syntaxhighlight>
</syntaxhighlight>


=== Flickering RGB Led ===
=== Flickering RGB Led ===

Revision as of 17:07, 14 April 2013

setup()

best to set the pins used for programming via USB again as outputs and low, before starting your program

void setup()
{ // Set pins
 
  pinMode(0, OUTPUT);
  pinMode(1, OUTPUT);
  pinMode(2, OUTPUT);
  digitalWrite(0, LOW);
  digitalWrite(1, LOW);
  digitalWrite(2, LOW);
 

}

PWM Heartbeat

/*
babygnusbuino: Fading


 */


int PWM_Pin = 0;    // LED connected to digital pin 0
int PWM_value = 0;

int wait = 30;

volatile unsigned char e = 0;
 
void setup()
{  
  // Timer Init
  TCCR0A = (0 << WGM02) | (0 << WGM01) | (0<< WGM00);    // Normal Mode 000
  TCCR0B = (0 << CS02) | (0 << CS01) | (1<< CS00);       // Clock Select no prescaling 001
  TIMSK = (1 << TOIE1);                                  // Overflow interrupt is enabled
  sei();                                                 // set Global Interrupt Enable

 
  // Set pins
  pinMode(PWM_Pin, OUTPUT);
  digitalWrite(0, LOW);

}
 
void loop()
{
 
  for (int c = 0; c < 255; c++) {
    PWM_value = c; 
    delay (wait);
  }
  
  for (int c = 255; c > 0; c--) {
    PWM_value = c; 
    delay (wait);
  }
  
}
 
 
//Overflow routine for Timer 1
ISR(TIM1_OVF_vect) {
 
  if(e==255) {
     e=0;
     digitalWrite(PWM_Pin, HIGH);
  }
 
  if (PWM_value == e) {  
     digitalWrite(PWM_Pin, LOW);
  }

  e++;
}

3 Channels PWM

/*
babygnusbuino: PWM 3 Channels


 */


int PWM_Pin0 = 0;    // LED connected to digital pin 0
int PWM_Pin1 = 1;    // LED connected to digital pin 0
int PWM_Pin2 = 2;    // LED connected to digital pin 0

int PWM_Pin0_value = 0;
int PWM_Pin1_value = 0;
int PWM_Pin2_value = 0;

int wait = 300;

volatile unsigned char e = 0;
 
void setup()
{  
  // Timer Init
  TCCR0A = (0 << WGM02) | (0 << WGM01) | (0<< WGM00);    // Normal Mode 000
  TCCR0B = (0 << CS02) | (0 << CS01) | (1<< CS00);       // Clock Select no prescaling 001
  TIMSK = (1 << TOIE1);                                  // Overflow interrupt is enabled
  sei();                                                 // set Global Interrupt Enable

  // Set pins
  pinMode(PWM_Pin0, OUTPUT);
  pinMode(PWM_Pin1, OUTPUT);
  pinMode(PWM_Pin2, OUTPUT);
 
}
 
void loop()
{
 
  for (int c = 0; c < 255; c++) {
    PWM_Pin2_value = c; 
    delay (wait);
  }
  
  for (int c = 255; c > 0; c--) {
    PWM_Pin2_value = c; 
    delay (wait);
  }
 
}
 
//Overflow routine for Timer 1
ISR(TIM1_OVF_vect) {
 
  if(e==255) {
     e=0;
     digitalWrite(PWM_Pin0, HIGH);
     digitalWrite(PWM_Pin1, HIGH);
     digitalWrite(PWM_Pin2, HIGH);

    }
 
  if (PWM_Pin0_value == e) {  
     digitalWrite(PWM_Pin0, LOW);
  }
  
  if (PWM_Pin1_value == e) {  
     digitalWrite(PWM_Pin1, LOW);
  }
  
  if (PWM_Pin2_value == e) {  
     digitalWrite(PWM_Pin2, LOW);
  }

  e++;
}

RGB Led

// based largely on Atmel's AVR138: Low-Jitter Multi-Channel Software PWM Application Note:
// http://www.atmel.com/dyn/resources/prod_documents/doc8020.pdf
 
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
 
#define CHMAX 3 // maximum number of PWM channels
#define PWMDEFAULT 0x00 // default PWM value at start up for all channels
 
#define RED_CLEAR (pinlevelB &= ~(1 << RED)) // map RED to PB4
#define GREEN_CLEAR (pinlevelB &= ~(1 << GREEN)) // map GREEN to PB3
#define BLUE_CLEAR (pinlevelB &= ~(1 << BLUE)) // map BLUE to PB0
 
//! Set bits corresponding to pin usage above
#define PORTB_MASK  (1 << PB4 | 1 << PB3| 1 << PB0)
 
#define set(x) |= (1<<x) 
#define clr(x) &=~(1<<x) 
#define inv(x) ^=(1<<x)
 
#define RED 		PB4
#define GREEN 		PB3
#define BLUE 		PB0
#define LED_PORT 	PORTB
#define LED_DDR 	DDRB

// function prototypes
void delay_ms(uint16_t ms);
void init();
void blend(int r, int g, int b, int da); 
 
// global variables
unsigned char compare[CHMAX];
volatile unsigned char compbuff[CHMAX];
unsigned long lfsr = 1;
unsigned char temp;

int main() {
	
	init();
	
	for (;;) { // forever
			
		lfsr = (lfsr >> 1) ^ (-(lfsr & 1u) & 0xd0000001u); // taps 32 31 29 1
		temp = (unsigned char) lfsr; // take lowest eight bits
		temp = (unsigned char) (lfsr >> 24);
		int r = temp & 0xff;
		
		lfsr = (lfsr >> 1) ^ (-(lfsr & 1u) & 0xd0000001u); // taps 32 31 29 1
		temp = (unsigned char) lfsr; // take lowest eight bits
		temp = (unsigned char) (lfsr >> 24);
		int g = temp & 0xff;
		
		lfsr = (lfsr >> 1) ^ (-(lfsr & 1u) & 0xd0000001u); // taps 32 31 29 1
		temp = (unsigned char) lfsr; // take lowest eight bits
		temp = (unsigned char) (lfsr >> 24);
		int b = temp & 0xff;
		
		for (int a = 0; a < 64; a++) { 
			_delay_ms(20);
			blend(r,g,b,a); // r g b alpha    
		}
		
	}
}
 
 
void delay_ms(uint16_t ms) {
  while (ms) {
    _delay_ms(1);
    ms--;
  }
}
 
void init(void) {
  // set the direction of the ports
  LED_DDR set(RED);
  LED_DDR set(GREEN);
  LED_DDR set(BLUE);
  
  unsigned char i, pwm;
 
  CLKPR = (1 << CLKPCE);        // enable clock prescaler update
  CLKPR = 0;                    // set clock to maximum (= crystal)
 
  pwm = PWMDEFAULT;
 
  // initialise all channels
  for(i=0 ; i<CHMAX ; i++) {
    compare[i] = pwm;           // set default PWM values
    compbuff[i] = pwm;          // set default PWM values
  }
 
  TIFR = (1 << TOV0);           // clear interrupt flag
  TIMSK = (1 << TOIE0);         // enable overflow interrupt
  TCCR0B = (1 << CS00);         // start timer, no prescale
 
  sei();
}
 
 
ISR (TIM0_OVF_vect) {
  static unsigned char pinlevelB=PORTB_MASK;
  static unsigned char softcount=0xFF;
 
  PORTB = pinlevelB;            // update outputs
  
  if(++softcount == 0){         // increment modulo 256 counter and update
                                // the compare values only when counter = 0.
    compare[0] = compbuff[0];   // verbose code for speed
    compare[1] = compbuff[1];
    compare[2] = compbuff[2];
 
    pinlevelB = PORTB_MASK;     // set all port pins high
  }
  // clear port pin on compare match (executed on next interrupt)
  if(compare[0] == softcount) RED_CLEAR;
  if(compare[1] == softcount) GREEN_CLEAR;
  if(compare[2] == softcount) BLUE_CLEAR;
}


/*
blend color
@param r Red
@param g Green
@param b Blue
@param da Alpha: the factor how much the new color will be blended with the existing color. da = 0: no change, da = 255: new color will be set (no blending).
*/
void blend(int r, int g, int b, int da) {
  
  // source alpha
  int sa = 255 - da;
  
  int tr = (sa * compbuff[0] + da * r) + 128;
  int tg = (sa * compbuff[1] + da * g) + 128;
  int tb = (sa * compbuff[2] + da * b) + 128;
  
  compbuff[0] = ((tr>>8)+tr)>>8;
  compbuff[1] = ((tg>>8)+tg)>>8;
  compbuff[2] = ((tb>>8)+tb)>>8;
  
}

Flickering RGB Led

/*
flickering RGB LED! 
*/
#include <avr/io.h>
#include <util/delay.h>

unsigned long lfsr = 1;
unsigned char temp;

/**
 * delay
 * @param ms duration in milliseconds
 */
void delay_ms(uint16_t ms)
{
  for (uint16_t i = 0 ; i < ms ; i++) {
    _delay_ms (1); // Loop delay
  }
}
 
void setup()
{
  DDRB = 0xff;
}

void loop() {  
  lfsr = (lfsr >> 1) ^ (-(lfsr & 1u) & 0xd0000001u); /* taps 32 31 29 1 */
  temp = (unsigned char) lfsr; // take lowest eight bits
  DDRB = ~temp; // declare those pins as output where temp is zero
  PORTB = temp << 2; // give the value of 0 to the output pins
  temp = (unsigned char) (lfsr >> 24);
  _delay_loop_2(temp<<7);
  delay_ms(100);
}

8-bit Noise

/* Pseudo-Random Bit Sequence Generator                     2009-11-25 */
/* Copyright (c) 2009 John Honniball, Dorkbot Bristol                  */
 
/*
 * For a discussion of PRBS generators, see The Art Of Electronics, by
 * Horowitz and Hill, Second Edition, pages 655 to 660. For more info
 * on Linear Feedback Shift Registers, see Wikipedia:
 *   http://en.wikipedia.org/wiki/Linear_feedback_shift_register
 * For the actual shift register taps, refer to this article on noise
 * generation for synthesisers:
 *   http://www.electricdruid.net/index.php?page=techniques.practicalLFSRs
 */
 
// Choose the same pin as the "Melody" example sketch
int speakerPin = 0;
 
int potiPin = A3;
 
unsigned int analogValue;
 
int samplingDelay;
 
unsigned long int reg;
 
void setup ()
{
  // Serial setup for debugging only; slows down the program far too much
  // for audible white noise
  //Serial.begin (9600);
 
  // Connect a piezo sounder between Ground and this pin
  pinMode (speakerPin, OUTPUT);
 
 
  // Arbitrary inital value; must not be zero
  reg = 0x551155aaL;
}
 
 
void loop ()
{
  unsigned long int newr;
  unsigned char lobit;
  unsigned char b31, b29, b25, b24;
 
  // Extract four chosen bits from the 32-bit register
  b31 = (reg & (1L << 31)) >> 31;
  b29 = (reg & (1L << 29)) >> 29;
  b25 = (reg & (1L << 25)) >> 25;
  b24 = (reg & (1L << 24)) >> 24;
 
  // EXOR the four bits together
  lobit = b31 ^ b29 ^ b25 ^ b24;
 
  // Shift and incorporate new bit at bit position 0
  newr = (reg << 1) | lobit;
 
  // Replace register with new value
  reg = newr;
 
  // Drive speaker pin from bit 0 of 'reg'
  digitalWrite (speakerPin, reg & 1);
 
  // Display 'reg' in the serial console for debugging only 
//  Serial.println (reg, HEX);
  samplingDelay = 1 + (2*(analogRead(potiPin)>>0));
  // Delay corresponds to 20kHz, but the actual frequency of updates
  // will be lower, due to computation time and loop overhead
  delayMicroseconds (samplingDelay);
 
  // If the above delay is increased to a few tens of milliseconds,
  // and the piezo sounder is replaced by an LED and a suitable series
  // resistor, a randomly flashing light will result. Several LEDs
  // could be driven from various bits of the shift register.
}


Crazy shit 8-bit symphony generator

/* Crazy shit 8-bit symphony generator                   */
/*     */
 
/*
 * inspired by:
 *  http://countercomplex.blogspot.com/2011/10/algorithmic-symphonies-from-one-line-of.html
 */
 
int speakerPin = 0;
 
int potiPin = A3;
 
long t = 0; 
int v = 0; 
int c = 0;

unsigned int analogValue;
 
void setup ()
{
  // Connect a piezo sounder between Ground and this pin
  pinMode (speakerPin, OUTPUT);

 
}
 
 
void loop ()
{
  /*
  for(t=0;;t++){
    c = (analogRead(potiPin)>>3); 
    v=t*((t>>14|t>>(8))&c&t>>c);
    analogWrite (speakerPin, v);
  }
  */
  
  for(t=0;;t++){
    c = (analogRead(potiPin)>>4); 
    v=t*((t>>5|t>>11)&c&t>>c);
    analogWrite (speakerPin, v);
  }
  
  /*
    for(t=0;;t++){
    c = (analogRead(potiPin)>>4); 
    v=t*((t>>7|t>>(c+4))&(c)&t>>(c*3));
    analogWrite (speakerPin, v);
  }
  */
  
}