Lautstärke steuern per Ultraschall

Weiß jemand von euch wie man mit diesem Digitalen Potentiometer umgeht?
http://www.analog.com/static/imported-files/images/pin_diagrams/AD5263_pc1.gif

Du musst bei ICs generall erst mal ins Datenblatt schauen.

AD5263 Datenblatt:
http://www.analog.com/static/imported-files/data_sheets/AD5263.pdf

Ansteuerung erfolgt über I2C oder SPI. SPI will da aber 10 Bit und Arduino macht nur 8 Bit. Also bleibt I2C. Das geht mit den üblichen 8 Bit Adressen + 8 Bit Daten.

RTC Libs sind da ein guter Anhaltspunkt. Sind aber immer nur ein paar Zeilen für Senden und Lesen. Um die ganzen Timing Diagramme und Start/Stop Conditions brauchst die du dich da NIE zu kümmern. Die schickst immer nur Adressen und/oder Daten und die Lib setzt das für dich um.

Das Datenformat ist auf Seite 16 erklärt. Da muss man sich dann erst mal entsprechend die Bytes zusammenbasteln. Man schickt drei Bytes: Address + Instruction + Data

Address wird an den Pins außen eingestellt. Kann bei einem Device immer 0 sein. Dann muss man da ein Bit für Read/Write setzen
Instruction enthält ein paar Status Bits. Hier wird auch eingestellt welches der 4 Potis man beschreibt
Das Data Byte enthält dann den Widerstandswert von 0-255

Sieht nicht so extrem kompliziert aus.

Ich würde dir da aber empfehlen was in DIP zu nehmen. Nicht SMD wie das hier. Die Dinger gibt es in DIP8. Oder willst du das weil es 15V macht? Die meisten können nämlich nur 5V.

EDIT:
Hier ist Code für Senden:

void write(byte addr, byte instruction, byte data)
{
      Wire.beginTransmission(addr)
      Wire.write(instruction);
      Wire.write(data);
      Wire.endTransmission();
}

Das kannst du dann so machen, dass du da z.B. die Nummer des Potis übergibst (jedes IC hat 4) und dann intern das Instruction Byte daraus erzeugst. Man kann auch das Adress-Byte intern festlegen und braucht es nicht als Parameter.

Leider ist mir das mit dem SMD etwas zu spät gekommen und ich habe die Dinger einfach so gekauft...bis ich dann gestern die große Überraschung :fearful: hatte dass ich die Dinger so nicht benutzen kann :0 . Ich würde die Potis liebend gern zurückschicken und mir größere und handlichere kaufen. Wo gibt es die DIP8? Ich habe noch nirgends solche gefunden.
Eigentlich würde mir auch ein einfacheres 2 kanal (Stereo) poti tun. Habt ihr eine Idee was sich da zur Audio Lautstärke steuerung gut eignet und auch leicht zu bedienen ist?Bestens eins mit über 64 Schritte Auflösung. Aber 64 ist eigentlich auch i.O. oder?
Welcher widerstand ist für Die Lautstärkeregelung ( Signal von einem Klinkekabel) am besten geeignet?
5v ist völlig in Ordnung
Danke für deinen Beitrag!
MFG Max

Jetzt wo du es hast wäre ein SSOP/DIP Adapter noch gut:
http://www.ebay.de/itm/SOIC24-SOIC-24-SSOP24-SSOP-24-Adapter-PCB-SMD-Convert-DIP-US-/150976619402?pt=LH_DefaultDomain_0&hash=item2326e8638a

Ist halt ne Frage des Lötens. Wie man bei der Platine sieht, ist SSOP viel, viel kleiner als SOIC. Aber mit Flussmittel geht das auch per Hand. Man muss nicht jeden Pin einzeln anlöten. Dazu gibt es Anleitungen und Videos wenn du es dir zutraust.

Wegen DIP musst du nur bei Standard-Elektronik-Versendern suchen:
http://www.reichelt.de/ICs-MCP-3-5-/2/index.html?&ACTION=2&LA=2&GROUPID=5472;SID=11UdZ-eH8AAAIAABbXhRM787fd1022a781af0bf1a78c4ae8d6857
(rechts oben auf Potis eingrenzen)

Achte da auch darauf ob du eins willst, dass einen Wert in einem EEPROM behält. Das haben nicht alle. In dem Datenblatt ist auch ne Liste was die Unterschiede genau sind:

Wenn du nach "Arduino digital potentiometer" suchst, gibt es massig Hits. Die sind halt oft etwas verschieden. Microchip ist da eine Ausnahme. Für das MCP4151 gibt es hier fertigen Code:
http://playground.arduino.cc//Code/Mcp4261

Da ist unten eine Liste mit was das alles damit grob kompatibel ist. Da würde ich was aus der Serie nehmen. Die sollten alles abdecken.

Reichelt hat halt Mindestbestellwert. Aber die Dinger gibts auch woanders :slight_smile:

Oder hier ist was mit einem MCP41100:

Das könnte dann wieder ähnlich zu anderen in der Serie sein. Ab wie du da siehst ist da nicht viel Code. Zwei Bytes mit SPI senden.

Ich habe mich für die erste Variante entschieden...die Platine hab ich sofort bestellt. :smiley:
Mit dem Löten wird es eher weniger Probleme geben da meine Tante paar Jahre als Löterin gearbeitet hat werde ich sie einfach ganz nett darum fragen :wink:

Kann ich diesen Code auch für meinen Verwenden ???: http://arduino.cc/en/Tutorial/SPIDigitalPot
Die Potis sind im Prinzip (bis auf die Kanäle) doch die Selben?
Danke für deine Hilfe! Ich war heute schon den ganzen Tag beschäftigt das Layout für so ein Adapter zu erstellen und die Ätz-Utensilien zu organisieren :blush:
Der Adapter kommt gerade richtig! Außerdem ist er im Verhältnis gesehen viel Billiger als wenn man es selber machen würde.

MFG

Ich muss mich da auch erst einlesen. Ich habe vor Jahren einmal damit was gemacht. Und das was ich hatte war weder I2C noch SPI. Das hatte glaube ich nur zwei Eingänge wo man mit Impulsen inkrementiert und dekrementiert hat.

Wenn man ins Datenblatt schaut, sieht man das das Datenformat der zwei ICs in der Tat genau gleich ist :slight_smile:
Seite 15 beim AD5263 und Seite 8 beim AD5204/06

Ich glaube ich habe jetzt vielleicht auch verstanden wieso das mit 10 Bit geht wenn man wirklich 16 Bit sendet. Das Schieben erfolgt MSB first. Wenn also der Puffer im IC 10 Bit hat, heißt dass man schiebt die ersten 6 Bit aus dem anderen Ende heraus und es bleiben nur die letzten 10 Bit drin. Diese werden mit der steigenden Flanke von CS übernommen.

Wenn es da steht kann man es mal so probieren :slight_smile:

SPI.bitOrder(MSBFIRST); schadet auch nichts.

Und wenn das nicht geht gibt es wie gesagt noch I2C als Alternative. SPI und I2C wird mit Pin 9 ausgewählt. Da muss man dann mehr mit einzelnen Bits rumfummeln, aber es steht alles da (Seite 16 und 19). Man muss z.B. im Adress Byte die obersten 5 Bits auf 01011 setzen und das unterste Bit auf 0. Bits 1 und 2 sind die Adresse des ICs per Pins 13 und 14. Du hast nur eins. Also setzt man die auch auf Low. Somit musst du da immer 0x58 als Adresse schicken.

Im Instruction Byte sind Bits 5 und 6 die Kanal Auswahl. Der Rest kann Low sein. Man macht also das:
byte instruction = channel << 6;

Oder ausgeschrieben:

void write(byte channel, byte value)
{
      Wire.beginTransmission(0x58)
      byte instruction = channel << 6
      Wire.write(instruction);
      Wire.write(value);
      Wire.endTransmission();
}

Aber denke mal selbst drüber nach. Kann auch sein, dass da noch ein Fehler drin ist.

Eigentlich ganz einfach.

Wäre dann so(Anhang) die Verkabelung?

Schaltplan AD5263.png

So nen großen Monitor hab ich nicht, mach mal bitte kleiner :astonished:

Hier die Kleinere Version.
Wenn ihr die Datei downloadet gehts besser.

Sieht insgesamt schlüssig aus, hab's aber nicht auf's Pinout geprüft.

Heute sind meine Sensoren gekommen ...ich habe den code noch an paar Stellen optimiert. Nur diese eine Stelle tut nicht...
Ich bin ehrlich gesagt auch selber von diesem code nicht überzeugt :smiley:

 // Vorwärts/Rückwärts -Steuerung und Erkennung der Wischrichtung
if (cm > og && cm2 > og){
  if (cm < maxhoehe)
  boolean sensor1hand = true;
  delay(99);
 sensor1hand = false;
  
  }
  if (cm2 < maxhoehe2){
   boolean sensor2hand = true;
   delay(99);
  sensor2hand = false;
  }
  // Bewegung von links nach rechts
 if (sensor1hand == true){
    delay(100);
   if (sensor2hand == true && sensor1hand == false ){
     delay(100);
     if(sensor1hand == false && sensor2hand == false){
     next = true;
     }
     
  }  
  // Bewegung von rechts nach links
  if (sensor2hand == true){
    delay(100);
   if (sensor2hand == false && sensor1hand == true ){
     delay(100);
     if(sensor1hand == false && sensor2hand == false){
     last = true;
         
     }
  }  
 }
 }

hier noch eine Andere Idee...allerdings funktioniert diese genau so wenig :confused:

 // Vorwärts/Rückwärts -Steuerung und Erkennung der Wischrichtung

  if (cm < maxhoehe && cm > og){
  sensor1hand = true;
  }
   else{
     sensor1hand = false;
     }
   if (cm2 < maxhoehe2 && cm2 > og){
   sensor2hand = true;
   }
   else{
     sensor2hand = false;
      }
    
     if (sensor2hand == true ){
      previousmillis2=millis();
      if (millis() < previousmillis2 + interval && sensor1hand == true) {
         previousmillis2 = millis();
        if (millis() < previousmillis2 + interval && sensor1hand == true && sensor2hand == false){
           previousmillis2 = millis();
          if (millis() < previousmillis2 + interval && sensor1hand == false && sensor2hand == false ) {
            next = true;
            
  }}}}}
if (cm > og && cm2 > og){
  if (cm < maxhoehe)
  boolean sensor1hand = true;
  delay(99);
 sensor1hand = false;  
  }

Was willst Du machen?
Der Code kontrolliert ob cm und cm2 größer als og sind.
Wenn cm kleiner als maxhoehe ist geht sensor1hand für 99 mS auf TRUE und dann wieder auf FALSE ansonsten wartet der Code 99 mS und setzt sensor1hand auf FALSE.
Ich würde sagen da feht eine geschwungene Klammer.

Grüße Uwe

Ich möchte die 2 Sensoren parallel anordnen und wenn man nun die Hand von links nach rechts über den Sensoren bewegt soll next true sein. Anders rum soll last true werden

Hat niemand eine Idee wie man den Code umschreiben kann dass er tut? Oder einen anderen Weg um das (mit den Sensoren) zu schaffen?

Bitte. Ich muss das für die Schule machen und muss es bald abgeben.

Kannst du nicht einfach wenn ein Sensor auslöst schauen ob innerhalb einer bestimmten Zeit der andere ausgelöst wird? Das kann man mit booleans gegeneinander verriegeln und die Zeit mit millis() messen.

Das ist ja auch glaube was du willst, aber bei sowas ist es sehr schwer Code zu schreiben ohne die Hardware zu haben und das zu testen. Man kann es vielleicht mit Tastern simulieren.

Das mit den Millis usw.(ganz unten in meinem Code ab " // Vorwärts/Rückwärts -Steuerung und Erkennung der Wischrichtung")habe ich schon probiert aber es funktioniert nicht. Irgend was klappt nicht...Die "Play/Pause" Funktion klappt soweit.

	//* +V connection of the Sensor attached to +5V
	//* GND connection of the Sensor attached to ground
        //* triggeer2 connection of the Sensor attached to digital pin 5
        //* echo2 connection of the Sensor attached to digital pin 6
	//* trigger1 connection of the Sensor2 attached to digital pin 7
        //* echo1 connection of the Sensor2 attached to digital pin 8
        //* Relais SIG on digital pin 9
        //* Poti SIG on digital pin 10
        
#include <Wire.h> // DigitalPoti        
const int ug = 10; // UNTERGRENZE in cm 
const int og = 11; // OBERGRENZE in cm
const int potiPin = 10;
unsigned long interval = 1000; 
unsigned long previousmillis = 0;
unsigned long previousmillis2 = 0;
// Sensor 2
const int trigger2 = 5;
const int echo2 = 6;
//sensor 1
const int trigger1 = 7;
const int echo1= 8;

long duration, cm;
long duration2, cm2;
long duration3, cm3;
long duration4, cm4;
const int relais = 9;
int protzentsensor = 0;
int schrittepoti = 0;
boolean sensor1hand = false;
boolean sensor2hand = false;
boolean pause = false;
boolean pause2 = false;
boolean play = false;
boolean play2 = false;
boolean next = false;
boolean last = false;
boolean isplaying = false;
boolean isplaying2 = false;

int maxhoehe;
int maxhoehe2;
byte val = 50; //DigitalPoti

void setup() {
  pinMode(trigger1, OUTPUT);
  pinMode(echo1, INPUT);
  pinMode(trigger2, OUTPUT);
  pinMode(echo2, INPUT);

pinMode(relais,OUTPUT);
Wire.begin(); //DigitalPoti
 
 //Kalibrierung am Start zur Ermittlung der Maximalen höhe 
 //(falls man direkt unter der Decke ist oder so, schließlich sind viele Decken keine 4m hoch ;D )
  Serial.begin(9600);
  
  
  digitalWrite(trigger1, LOW);
  delayMicroseconds(2);
  digitalWrite(trigger1, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigger1, LOW);
  duration3 = pulseIn(echo1, HIGH);
  cm3 = duration3/58.2;
  
  digitalWrite(trigger2, LOW);
  delayMicroseconds(2);
  digitalWrite(trigger2, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigger2, LOW);
  duration4 = pulseIn(echo2, HIGH);
  cm4 = duration4/58.2;
  
  maxhoehe = cm3-20;
  maxhoehe2 = cm4-20;
  
}
void loop()
{
  // DigitalPoti
  Wire.beginTransmission(44); // transmit to device #44 (0x2c)---> Datasheet
  Wire.write(byte(0x00));           
  Wire.write(val);             
  Wire.endTransmission();    

  //SonarSensor1
  digitalWrite(trigger1, LOW);
  delayMicroseconds(2);
  digitalWrite(trigger1, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigger1, LOW);
  duration = pulseIn(echo1, HIGH);
  cm = duration/58.2;
  
  //SonarSensor2
  digitalWrite(trigger2, LOW);
  delayMicroseconds(2);
  digitalWrite(trigger2, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigger2, LOW);
  duration2 = pulseIn(echo2, HIGH);
  cm2 = duration2/58.2;
  
// Serial.println(cm2);
  Serial.println(maxhoehe);
   Serial.println(maxhoehe2);

  // Reaktion auf Entfernung: Lautstärkeregulierung
   if ( cm||cm2 > ug && cm||cm2 < og ){
     int protzentsensor1 = 100/(og-ug)*(cm-ug);
     int protzentsensor2 = 100/(og-ug)*(cm2-ug);
  
  //  Die Kleinere Entfernung wird genommen.
       if (protzentsensor1 < protzentsensor2){
        protzentsensor = protzentsensor1;
      }
       if (protzentsensor2 < protzentsensor1){
        protzentsensor = protzentsensor2;
      }
     }
   
     schrittepoti = 2,56*protzentsensor;
     val = schrittepoti;
     
  // Pause / Play Steuerung 
  if (cm < ug && isplaying == true){
    pause = true;
   }
    if (cm2 < ug && isplaying2 == true){
    pause2 = true;
   }
  if (cm2 > ug && isplaying2 == false){
    play2 = true;
   }
     if (cm > ug && isplaying == false){
    play = true;
   }
   
// Relais Befehle zur Klinkenschaltung
 if (pause == true ) {
   digitalWrite(relais, HIGH);
   delay(50);
   digitalWrite(relais, LOW);
   delay(50);
   pause = false;
   isplaying = false;
   delay(100);
   }
    if (play == true ) {
   delay(1000);
   digitalWrite(relais, HIGH);
   delay(50);
   digitalWrite(relais, LOW);
   delay(50);
   play = false;
   isplaying = true;
   
   }
   if (pause2 == true ) {
   digitalWrite(relais, HIGH);
   delay(50);
   digitalWrite(relais, LOW);
   delay(50);
   pause2 = false;
   isplaying2 = false;
   delay(100);
   }
    if (play2 == true ) {
   delay(1000);
   digitalWrite(relais, HIGH);
   delay(50);
   digitalWrite(relais, LOW);
   delay(50);
   play2 = false;
   isplaying2 = true;
  

   }
   if (next == true ) {
   digitalWrite(relais, HIGH);
   delay(50);
   digitalWrite(relais, LOW);
   delay(50);
   digitalWrite(relais, HIGH);
   delay(50);
   digitalWrite(relais, LOW);
   delay(50);
   next = false;
  }
  if (last == true ) {
   digitalWrite(relais, HIGH);
   delay(50);
   digitalWrite(relais, LOW);
   delay(50);
   digitalWrite(relais, HIGH);
   delay(50);
   digitalWrite(relais, LOW);
   delay(50);
   digitalWrite(relais, HIGH);
   delay(50);
   digitalWrite(relais, LOW);
   delay(50);
   last = false;
   }
 



 // Vorwärts/Rückwärts -Steuerung und Erkennung der Wischrichtung

  if (cm < maxhoehe && cm > og){
  sensor1hand = true;
  }
  else{
     sensor1hand = false;
     }
  
  if (cm2 < maxhoehe2 && cm2 > og){
   sensor2hand = true;
   }
   else{
     sensor2hand = false;
     
    }
    
    
    
    
 if (sensor2hand == true ){
      previousmillis2=millis();
      if (millis() < previousmillis2 + interval && sensor1hand == true) {
         previousmillis2 = millis();
        if (millis() < previousmillis2 + interval && sensor1hand == true && sensor2hand == false){
           previousmillis2 = millis();
          if (millis() < previousmillis2 + interval && sensor1hand == false && sensor2hand == false ) {
            next = true;
            }
             }}
 }
 }

Versuche mal das nacheinander abzufragen statt es ineinander zu verschachteln.

z.B. hier:

  if (millis() < previousmillis2 + interval && sensor1hand == true && sensor2hand == false){
           previousmillis2 = millis();
          if (millis() < previousmillis2 + interval && sensor1hand == false && sensor2hand == false ) {

Ich blick da nicht ganz durch, aber du fragst erst auf sensor1hand == true ab und dann eine Schleife darunter auf false. Das kann glaube ich nicht gehen.

Das mit der Schleife verstehe ich jetzt auch...desshalb bin ich jetzt umgestiegen auf die boolean variante die du mir empfohlen hast. wäre das ein Ansatz? leider tut es so aber in der Praxis auch noch nicht :~

 // Vorwärts/Rückwärts -Steuerung und Erkennung der Wischrichtung

  if (cm < maxhoehe && cm > og){
  sensor1hand = true;
  }
 if (cm >= maxhoehe && cm <= og){
     sensor1hand = false;
     }
  
  if (cm2 < maxhoehe2 && cm2 > og){
   sensor2hand = true;
   }
   if (cm2 >= maxhoehe2 && cm2 <= og){
     sensor2hand = false;
     
    }
    
    
    
    
  if (sensor2hand == true ){
      previousmillis2=millis();
      }
  if (millis() < previousmillis2 + interval && sensor1hand == true) {
         previousmillis2 = millis();
         voraussetzung1 = true;
         previousmillis4 = millis();
         }
  if ( millis() >  previousmillis4 + interval2){
     voraussetzung1 = false;
     }
  if (millis() < previousmillis2 + interval && sensor1hand == true && sensor2hand == false){
           previousmillis2 = millis();
           voraussetzung2 = true;
           previousmillis3 = millis();
           }
   if ( millis() >  previousmillis3 + interval2){
     voraussetzung2 = false;
     }
  if (millis() < previousmillis2 + interval && sensor1hand == false && sensor2hand == false && voraussetzung2 == true && voraussetzung1 == true ) {
            next = true;
            voraussetzung2 = false;
            voraussetzung1 = false;

}
 
 }

Ist das schon realisierbar, oder?