Hur ska man dela upp olika bittarna för SPI-kommunikation?

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
Användarvisningsbild
Al_Bundy
Inlägg: 2889
Blev medlem: 11 september 2012, 23:59:50
Ort: The U.S - Chicago
Kontakt:

Hur ska man dela upp olika bittarna för SPI-kommunikation?

Inlägg av Al_Bundy »

Nu ska jag tala med den digitala potentiometern MCP41010 och den har SPI kommunikationsfunktion.
Jag kommer använda mig utav Java när jag programmerar för processorn ARM Cortex-A53 samt biblioteket Pi4J.

Det jag först börjar med är att deklarera ett SPI objekt.

Kod: Markera allt

// Declare the SPI
spi = SpiFactory.getInstance(SpiChannel.CS1,
                SpiDevice.DEFAULT_SPI_SPEED, // default spi speed 1 MHz
                SpiDevice.DEFAULT_SPI_MODE); // default spi mode 0
För att skriva till MCP41010 så krävs det att man sätter alla ettor och nollor rätt. Det jag har börjat med är att först läsa databladet http://ww1.microchip.com/downloads/en/D ... 11195c.pdf Sidan 18

Där efter så har jag valt mitt kommando för att bestämma om jag ska skriva, stänga ned och vilken utgång som gäller. I java så kan man använda 0b eller 0B för att deklarera att talet är ett binärt tal.

Nu säger databladet att SPI klockan gör 16 pulser och jag tolkar som att inläsningen sker i en enda rad, dvs inget "start kommando" och sedan kommer "data". Det jag försöker säga är att om man ska skriva till MCP41010 så gäller det ett binärt tal som har 16 bit i längd.

Jag har valt denna bit som kommando 0b00010001 men denna har längden 8 bitar och jag behöver 8 bitar till. Då har jag två frågor:

1. Hur kan jag addera så att 0b00010001 + 00100100 eller likande blir 0b0001000100100100 i Java, utan att blanda in strängar och "fusk"-konvertering igenom bibliotek.

2. Visst kräver MCP41010 en hel bitt på 16 bitar, eller ska det vara uppdelning typ först kommando, och där efter registret? Se exempelkod nedan som visar en array som har två element. Eller ska det vara ett enda element?

Här är ett verkligt exempel på uppdelning: https://github.com/Pi4J/pi4j/blob/maste ... ample.java

Kod: Markera allt

byte[] data = new byte[] {
    			(byte) 0b00010001, // Commando
                        (byte) 0b01010010 // Register
    	};
    	
        // send conversion request to ADC chip via SPI channel
        spi.write(data);
Användarvisningsbild
lillahuset
Gått bort
Inlägg: 13969
Blev medlem: 3 juli 2008, 08:13:14
Ort: Norrköping

Re: Hur ska man dela upp olika bittarna för SPI-kommunikatio

Inlägg av lillahuset »

Jag har lite svårt att förstå vad du svamlar om men det kanske är javarelaterat.

Poten vill i vilket fall som helst ha två BYTE dvs sexton BIT. Första BYTEN är kommandot, andra BYTEN är värdet.

Det glädjer mig att du läser datablad till skillnad från majoriteten här. :wink:
Shimonu
Inlägg: 295
Blev medlem: 21 oktober 2015, 22:44:33

Re: Hur ska man dela upp olika bittarna för SPI-kommunikatio

Inlägg av Shimonu »

Du får skriva 2 bytes efter varandra
Användarvisningsbild
Al_Bundy
Inlägg: 2889
Blev medlem: 11 september 2012, 23:59:50
Ort: The U.S - Chicago
Kontakt:

Re: Hur ska man dela upp olika bittarna för SPI-kommunikatio

Inlägg av Al_Bundy »

lillahuset skrev:Jag har lite svårt att förstå vad du svamlar om men det kanske är javarelaterat.

Poten vill i vilket fall som helst ha två BYTE dvs sexton BIT. Första BYTEN är kommandot, andra BYTEN är värdet.

Det glädjer mig att du läser datablad till skillnad från majoriteten här. :wink:
Java är inget svammel. Börjar bli rätt så populärt att programmera ARM processorer i Java. Det är inte direkt det snabbaste språket, men man kan iallafall göra mycket grafiskt och koppla ihop GPIO pinnarna med webbapplikationer. Vilket är badass nu för tiden.

Tack! Okej! Det blir alltså en array med två element.

Kod: Markera allt

byte[] data = new byte[] {
    			(byte) 0b00010001, // Commando
    			(byte) 0b00000000 // Register
    	};
    	
Men då är frågan. Jag misstänker att om jag ändrar register till 255 i binärtal så betyder det att jag säger åt digitala potentiometern att ha maximal resistans, dvs 10 KOhm. Så det skulle vara intressant hur man kan ändra detta 0b00000000 till allt mellan binär 255 och binär 0. Binär noll är ju redan 0b00000000.

Jag brukar alltid läsa datablad(och alltid köra fast :oops: )

Edit:

Här är vad jag tror det ska vara. Jag använder mig av OR-operatorn | . Först kastar jag om variabeln dac to byte och sedan sätter jag 0b00000000 eller dac. I detta fall betyder det att jag "adderar" 0b0000000 med dac.

Kod: Markera allt

byte[] data = new byte[] {
    			(byte) 0b00010001, // Commando
    			(byte) (0b00000000 | dac) // Register
    	};
Användarvisningsbild
Al_Bundy
Inlägg: 2889
Blev medlem: 11 september 2012, 23:59:50
Ort: The U.S - Chicago
Kontakt:

Re: Hur ska man dela upp olika bittarna för SPI-kommunikatio

Inlägg av Al_Bundy »

Fungerade inte. :evil:

Jag testade även detta.

Kod: Markera allt

short[] data = new short[] {
    			(short) 0b00010011, // Commando
    			(short) (0b11111111) // Register 255
    	};
schnilsch
Inlägg: 76
Blev medlem: 11 juni 2014, 18:14:16

Re: Hur ska man dela upp olika bittarna för SPI-kommunikatio

Inlägg av schnilsch »

Det kanske är så att du inte drar CS låg innan du skickar data?
Användarvisningsbild
Klas-Kenny
Inlägg: 11328
Blev medlem: 17 maj 2010, 19:06:14
Ort: Växjö/Alvesta

Re: Hur ska man dela upp olika bittarna för SPI-kommunikatio

Inlägg av Klas-Kenny »

Kör du SPI'et i 8bit eller 16bit-mode?

Kör du det i 8bit mode och inte sköter CS-signalen själv i kod så drar sannolikt processorn CS hög för ett ögonblick, mellan varje sänt byte. Det lär inte slaven tycka om då den förväntar sig 16b-paket.

Edit: Samt, har du mätt på vad som faktiskt kommer ur processorn eller grundar du "det funkar inte" i att inte slaven gör det du förväntar dig?
En annan sak att hålla rätt på är ordningen som bitarna klockas ut, om det är MSB först eller LSB först.
Användarvisningsbild
Al_Bundy
Inlägg: 2889
Blev medlem: 11 september 2012, 23:59:50
Ort: The U.S - Chicago
Kontakt:

Re: Hur ska man dela upp olika bittarna för SPI-kommunikatio

Inlägg av Al_Bundy »

Hej Klas-Kenny och schnilsch! Här kommer det ett långt inlägg.

Jag använder mig av en Raspberry Pi B+, även kallat ARM Cortex A53 processor. Jag använder mig utav Java openJDK 8 som har stöd för ARM processorer tills Januari 2019. Där efter blir OpenJDK 11 som gäller för ARM.

Mina GPIO pinnar på pajen och MCP41010 ser ut så här som nedan visar.
Då har jag kopplat ihop:

* VDD = 3.3 VDC
* PDB0 = 3.3 VDC
* PW0 = Lysdioden's positiva pinne
* PA0 = Ground tillsammans med Lysdiodens jordpinne
* CS = GPIO 10
* SCK = GPIO 14
* SI = GPIO 12
* Vss = Ground

Koden för programmet ser ut så här:

Kod: Markera allt

import java.io.IOException;

import com.pi4j.io.spi.SpiChannel;
import com.pi4j.io.spi.SpiDevice;
import com.pi4j.io.spi.SpiFactory;

public class Raspberry {
	// SPI device
    public SpiDevice spi = null;
    
    public Raspberry() throws IOException {
    	// Declare the SPI
    	spi = SpiFactory.getInstance(SpiChannel.CS0,
                SpiDevice.DEFAULT_SPI_SPEED, // default spi speed 1 MHz
                SpiDevice.DEFAULT_SPI_MODE); // default spi mode 0
    }
    
    public void setResistans(short dac, boolean status) throws IOException {
    	
    	
    	byte[] data = new byte[] {
    			(byte) 0b00010001, 
    			(byte) 0b11111111 // Register 255
    	};
    	
    	
        // send conversion request to ADC chip via SPI channel
        spi.write(data);

    
    }
}
Där anropar jag metoden setResistans(int dac, boolean status) från ett annat objekt som har hand om web applikationen.

Resultatet är att ingen lampa lyser.
Du har inte behörighet att öppna de filer som bifogats till detta inlägg.
Användarvisningsbild
Al_Bundy
Inlägg: 2889
Blev medlem: 11 september 2012, 23:59:50
Ort: The U.S - Chicago
Kontakt:

Re: Hur ska man dela upp olika bittarna för SPI-kommunikatio

Inlägg av Al_Bundy »

Klas-Kenny skrev:Kör du SPI'et i 8bit eller 16bit-mode?
Det måste vara 8 bit. Jag vet att det går att aktivera och avaktivera SPI via sudo raspi-config kommandot i terminalen hos min Paj. Det har jag gjort också. Det fungerar mycket bra för MCP3008 ADC.
Kör du det i 8bit mode och inte sköter CS-signalen själv i kod så drar sannolikt processorn CS hög för ett ögonblick, mellan varje sänt byte. Det lär inte slaven tycka om då den förväntar sig 16b-paket.
Hur ska jag få detta till 16 bit-paket?
Edit: Samt, har du mätt på vad som faktiskt kommer ur processorn eller grundar du "det funkar inte" i att inte slaven gör det du förväntar dig?
En annan sak att hålla rätt på är ordningen som bitarna klockas ut, om det är MSB först eller LSB först.
Jag har inte mätt något då jag inte har något oscilloskop. Önskar dock att köpa. Se min näst senaste tråd angående om det.
Användarvisningsbild
Klas-Kenny
Inlägg: 11328
Blev medlem: 17 maj 2010, 19:06:14
Ort: Växjö/Alvesta

Re: Hur ska man dela upp olika bittarna för SPI-kommunikatio

Inlägg av Klas-Kenny »

Verkar som att Raspberry Pi bara stödjer 8b-SPI.
Således får du hantera CS i mjukvara.

Använd CS-pinnen som en helt vanlig GPIO istället (eller använd någon annan pinne, som du kan använda som GPIO).

Ingen koll på hur det ser ut i Java, men lite pseudo-kod skulle helt enkelt vara:

Kod: Markera allt

SetGpioLow(CS_PIN);
Spi.write(data);
SetGpioHigh(CS_PIN);
Inte konstigare än så. Förutsatt att Spi.write är synkron, och inte utnyttjar några buffrar, dma eller annat finurligt.
Användarvisningsbild
Al_Bundy
Inlägg: 2889
Blev medlem: 11 september 2012, 23:59:50
Ort: The U.S - Chicago
Kontakt:

Re: Hur ska man dela upp olika bittarna för SPI-kommunikatio

Inlägg av Al_Bundy »

Jag lägger upp mitt projekt här. Projektet öppnas med Eclipse SimRel som finns kostnadsfritt att ladda ned.

Programmet måste köras på en Raspberry B+ eller nyare. Det nu gör är att installera openJDK 8 på eran paj.
sudo apt-get install openjdk-8-jdk
Där efter laddar ni ned Tomcat 8 http://apache.mirrors.spacedump.net/tom ... .53.tar.gz och packar upp den.

Då finns det två mappar som är intressant - webapps och bin. Radera allt innehåll i mappen webapps. Där efter går ni in till bin mappen och skriver
sudo sh startup.sh
Klart!

Sedan tar ni mitt projekt(FadingLED.zip) och paketera upp den. Där hittar ni FadingLED.war. Placera FadingLED.war i webapps mappen och då kommer Tomcat 8 att automatiskt packa upp FadingLED.war till en mapp.

Efter det är klart. Då går ni in på http://www.localhost:8080/FadingLED i eran webbläsare. Rör på "slidern" så att ni kan anropa metoden setResistans(int dac, boolean status). Argumenterna har dock ingen funktionalitet för nuvarande.
Du har inte behörighet att öppna de filer som bifogats till detta inlägg.
Användarvisningsbild
Al_Bundy
Inlägg: 2889
Blev medlem: 11 september 2012, 23:59:50
Ort: The U.S - Chicago
Kontakt:

Re: Hur ska man dela upp olika bittarna för SPI-kommunikatio

Inlägg av Al_Bundy »

Klas-Kenny skrev:Verkar som att Raspberry Pi bara stödjer 8b-SPI.
Således får du hantera CS i mjukvara.

Använd CS-pinnen som en helt vanlig GPIO istället (eller använd någon annan pinne, som du kan använda som GPIO).

Ingen koll på hur det ser ut i Java, men lite pseudo-kod skulle helt enkelt vara:

Kod: Markera allt

SetGpioLow(CS_PIN);
Spi.write(data);
SetGpioHigh(CS_PIN);
Inte konstigare än så. Förutsatt att Spi.write är synkron, och inte utnyttjar några buffrar, dma eller annat finurligt.
Okej! Jag ska testa detta! Återkommer. Raspberry Pi kan använda både 8 och 9 bit SPI. Men så denna MCP41010 kräver alltså 16 bit, och inte 8 bit + 8 bit?

Nej. Fungerar inte.

Kod: Markera allt

import java.io.IOException;

import com.pi4j.io.gpio.GpioController;
import com.pi4j.io.gpio.GpioFactory;
import com.pi4j.io.gpio.GpioPinDigitalOutput;
import com.pi4j.io.gpio.RaspiPin;
import com.pi4j.io.spi.SpiChannel;
import com.pi4j.io.spi.SpiDevice;
import com.pi4j.io.spi.SpiFactory;

public class Raspberry {
	// SPI device
    public SpiDevice spi = null;
    public GpioPinDigitalOutput CSpin;
    public GpioController gpio;
    
    public Raspberry() throws IOException {
    	// create gpio controller
        gpio = GpioFactory.getInstance();

        // provision gpio pin #01 as an output pin and turn on
        CSpin = gpio.provisionDigitalOutputPin(RaspiPin.GPIO_01);
    	
    	// Declare the SPI
    	spi = SpiFactory.getInstance(SpiChannel.CS0,
                SpiDevice.DEFAULT_SPI_SPEED, // default spi speed 1 MHz
                SpiDevice.DEFAULT_SPI_MODE); // default spi mode 0
    }
    
    public void setResistans(short dac, boolean status) throws IOException {
    	
    	
    	byte[] data = new byte[] {
    			(byte) 0b00010001, 
    			(byte) 0b11111111 // Register 255
    	};
    	
    	
        // send conversion request to ADC chip via SPI channel
    	CSpin.low();
        spi.write(data);
        CSpin.high();

    
    }
}
Användarvisningsbild
Icecap
Inlägg: 26139
Blev medlem: 10 januari 2005, 14:52:15
Ort: Aabenraa, Danmark

Re: Hur ska man dela upp olika bittarna för SPI-kommunikatio

Inlägg av Icecap »

Om SPI-funktionen kör med 8 bit kan det mycket väl vara att den aktiverar CS, skriver 8 bit och sedan deaktiverar CS. Vid nästa byte sker det samma igen.

Det som SKA utföras är:
Aktivera CS
Skicka byte 1
Skicka byte 2
Deaktivera CS.
Användarvisningsbild
lillahuset
Gått bort
Inlägg: 13969
Blev medlem: 3 juli 2008, 08:13:14
Ort: Norrköping

Re: Hur ska man dela upp olika bittarna för SPI-kommunikatio

Inlägg av lillahuset »

Om du inte lyckas på annat sätt kan jag rekommendera pigpio. Finns tydligen någon javawrapper för det också.
http://abyz.me.uk/rpi/pigpio/index.html#Other_Languages
Användarvisningsbild
Al_Bundy
Inlägg: 2889
Blev medlem: 11 september 2012, 23:59:50
Ort: The U.S - Chicago
Kontakt:

Re: Hur ska man dela upp olika bittarna för SPI-kommunikatio

Inlägg av Al_Bundy »

Nu har jag fått det att fungera.

Mystiskt nog så verkar det som att jag hade kompilerat med OpenJDK 11 och kört programmet med OpenJDK 8 :mrgreen:

Här är koden iallafall. Jag använder CS0 som CS-pinne.

Kod: Markera allt

import java.io.IOException;

import com.pi4j.io.gpio.GpioController;
import com.pi4j.io.gpio.GpioFactory;
import com.pi4j.io.gpio.GpioPinDigitalOutput;
import com.pi4j.io.gpio.RaspiPin;
import com.pi4j.io.spi.SpiChannel;
import com.pi4j.io.spi.SpiDevice;
import com.pi4j.io.spi.SpiFactory;

public class Raspberry {
	// SPI device
    public static SpiDevice spi = null;
    public static GpioPinDigitalOutput CSpin;
    public static GpioController gpio;

    
    public static void main(String args[]) {
    	System.out.println("Starting");
    	// create gpio controller
        gpio = GpioFactory.getInstance();

        // provision gpio pin #01 as an output pin and turn on
        CSpin = gpio.provisionDigitalOutputPin(RaspiPin.GPIO_01);
    	
    	// Declare the SPI
    	try {
			spi = SpiFactory.getInstance(SpiChannel.CS0,
			        SpiDevice.DEFAULT_SPI_SPEED, // default spi speed 1 MHz
			        SpiDevice.DEFAULT_SPI_MODE);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} // default spi mode 0
    	
    	System.out.println("Sett the resistanse now - 255");
    	setResistans();
    }
    
    public static void setResistans() {
    	
    	
    	byte[] data = new byte[] {
    			(byte) 0b00010001, 
    			(byte) 0b00000000 // Register 0 eller 0b1111111 för register 255
    	};
    	
    	
        // send conversion request to ADC chip via SPI channel
    	CSpin.low();
        try {
			spi.write(data);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
        CSpin.high();

    
    }
}
Nu måste jag tyvärr iväg och skruva i bilar. Men jag återkommer jag fortsätter med projektet och laddar upp detta för den som vill testa och leka sig fram med Java Server Faces + Primefaces med Pi4J.

:tumupp:
Skriv svar