kramann.info
© Guido Kramann

Login: Passwort:










kramann.info
© Guido Kramann

Login: Passwort:




Übung in Echtzeitsysteme: PWM für Servo erzeugen

(EN google-translate)

(PL google-translate)

Ausgehend von einem einfachen Programm und einer einfachen Verstärkerschaltung für den Audioausgang, soll ein Programm entwickelt werden, das es erlaubt direkt zwei Servos über den Auduiausgang angesteuert werden.

Teil 1 - Nachvollziehen eines einfachen Tests, um digitale Pulse an einen Mikrocontroller zu schicken

package processing.test.avrconnect1;

import processing.core.*; 

import android.media.AudioTrack;
import android.media.AudioFormat;
import android.media.AudioManager;

public class avrconnect1 extends PApplet {


boolean aktiv = false; 

int sr;
int buffsize;

//create an audiotrack object
AudioTrack audioTrack;

public int PULSE = 15;
public int pulse = 0;

short[] samples;
int amp = 10000;
float twopi = 2.0f*PI;
float fr = 440.0f;
float fr2 = 4.4f;
float fr4 = 1.1f;
float fr3 = 220.0f;
float ph = 0.0f;   
float ph2 = 0.0f;   
float ph3 = 0.0f;   
float ph4 = 0.0f;   
float change=0.0f;
float change2=0.0f;

Tonspieler tonspieler;


public void setup()
{
	sr = 44100;

	buffsize = AudioTrack.getMinBufferSize(sr, AudioFormat.CHANNEL_OUT_MONO, 
	        AudioFormat.ENCODING_PCM_16BIT);

	//create an audiotrack object
	audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, sr, 
	                                    AudioFormat.CHANNEL_OUT_MONO, 
	                                    AudioFormat.ENCODING_PCM_16BIT, 
	                                    buffsize, 
	                                    AudioTrack.MODE_STREAM);


	samples= new short[buffsize];
   
	tonspieler = new Tonspieler();
	
	Thread t = new Thread(tonspieler);
	t.start();
	audioTrack.play();
}

public void draw()
{
    clear();
    background(0);
    if(aktiv)    
        fill(0,255,0);
    else
        fill(255,0,0);    
    ellipse(width/2,height/2,width/2,height/2);

}

public void mousePressed()
{
    aktiv = !aktiv;
    pulse=0;
}

private class Tonspieler implements Runnable
{
	public void run()
	{
		int zaehler = 0;
		while(true)
		{
			if(aktiv)
			{
				  for(int i=0;i<buffsize;i++)
				  {  
					 if(zaehler<2 && pulse<PULSE)
					 {	 
					     samples[i] = Short.MAX_VALUE;
					     
					 }    
					 else
						 samples[i] = Short.MIN_VALUE;
//    					 samples[i] = (short)0;
				     zaehler++;
				     if(zaehler>=4)
				     {
				         pulse++;
				         zaehler=0;
				     }
				     
				  } 
				  audioTrack.write(samples, 0, buffsize);
				
			}
		}
	}
}


}

Code 0-1: Quelltext - Android-seitig

  • Erläuterung

Das Programm verschickt bei jedem Einschalten ( mousePressed(), aktiv==true ) 15 Rechteckpulse an den verbundenen Mikrocontroller.

android_eclipse_projekt.zip - Android/ Eclipse-Projekt zu obigem Quelltext.
#include<avr/io.h>

int main()
{
    unsigned char akku;
    unsigned char x;
    unsigned char zahl;
    
    DDRB=0;
	DDRA=0;
//	PORTA=255;
	PORTA=0;
	DDRC=255;

        akku=0;
	zahl=0;
	x=0;
	PORTC=zahl;




        while(1)
	{
	        akku=PINB;
		x=PINA;
	        if((akku & 0b00000001)>0)
		    zahl=0;
                if( (x & 0b00000001)>0)
		{
		    zahl++;
			while( (x & 0b00000001)>0)
			{
			    x=PINA;
			    DDRD=0;
			}
		}
		PORTC=zahl;
	}

}

Code 0-2: Mikrocontroller-Quelltext zum Versuch digitale Pulse über den Audio-Ausgang zu übertragen.

mikrocontroller_projekt.zip - zugehöriges Mikrocontroller-Projekt
Versuchsaufbau - digitale Pulse an Mikrocontroller übertragen.

Bild 0-1: Versuchsaufbau - digitale Pulse an Mikrocontroller übertragen.

Verwendete Verstärkerschaltung.

Bild 0-2: Verwendete Verstärkerschaltung.

Musterlösung
Verwendete Verstärkerschaltung für Servo-PWM-Signale.

Bild 0-3: Verwendete Verstärkerschaltung für Servo-PWM-Signale.

musterloesung.zip - Musterlösung: Wechsel zwischen -45 Grad, 0 Grad, +45 Grad über Touchscreen
package processing.test.avrconnect1;

import processing.core.*; 

import android.media.AudioTrack;
import android.media.AudioFormat;
import android.media.AudioManager;

public class avrconnect1 extends PApplet {


boolean aktiv = false; 

int sr;
int buffsize;
long PUFFERZEIT=0;
//create an audiotrack object
AudioTrack audioTrack;

public int PULSE = 400;
public int pulse = 0;

short[] samples;
int amp = 10000;
float twopi = 2.0f*PI;
float fr = 440.0f;
float fr2 = 4.4f;
float fr4 = 1.1f;
float fr3 = 220.0f;
float ph = 0.0f;   
float ph2 = 0.0f;   
float ph3 = 0.0f;   
float ph4 = 0.0f;   
float change=0.0f;
float change2=0.0f;

Tonspieler tonspieler;

int WERT = 0;

public void setup()
{
	sr = 44100;

	
	
	buffsize = AudioTrack.getMinBufferSize(sr, AudioFormat.CHANNEL_OUT_MONO, 
	        AudioFormat.ENCODING_PCM_16BIT);

	PUFFERZEIT = (1000*(long)buffsize)/sr;
	
	//create an audiotrack object
	audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, sr, 
	                                    AudioFormat.CHANNEL_OUT_MONO, 
	                                    AudioFormat.ENCODING_PCM_16BIT, 
	                                    buffsize, 
	                                    AudioTrack.MODE_STREAM);


	samples= new short[buffsize];
   
	tonspieler = new Tonspieler();
	
	Thread t = new Thread(tonspieler);
	t.start();
	audioTrack.play();
}

public void draw()
{
    clear();
    background(0);
    if(WERT==0)    
        fill(255,0,0);
    else if(WERT==1)
        fill(0,255,0);
    else
        fill(0,0,255);
    	
    ellipse(width/2,height/2,width/2,height/2);

}

public void mousePressed()
{
	WERT++;
	WERT%=3;
}

private class Tonspieler implements Runnable
{
	public void run()
	{
		int zaehler = 0;
		long zeit = System.currentTimeMillis();
		while(true)
		{
				  for(int i=0;i<buffsize;i++)
				  {  
					 if(zaehler<44+WERT*22)
					     samples[i] = Short.MAX_VALUE;
					 else
						 samples[i] = Short.MIN_VALUE;
				     zaehler++;
				     if(zaehler>=500)
				         zaehler=0;
				     
				  } 
				  audioTrack.write(samples, 0, buffsize);
				  
				  long restzeit = PUFFERZEIT-(System.currentTimeMillis()-zeit);
				  zeit=System.currentTimeMillis();
				  if(restzeit>0)
				  {
					  try
					  {
						  Thread.sleep(restzeit);
					  }
					  catch(Exception e)
					  {
						  
					  }
				  }
		}
	}
}


}

Code 0-3: Quelltext Musterlösung