-
Notifications
You must be signed in to change notification settings - Fork 62
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Issue while reading SPI data #405
Comments
I ordered this chip to see if I can duplicate your error. A couple things I will/would try with the chip.
I believe the pigpio spi always send 8 bits, have you tried as suggested ?
If you solve this please update the post, otherwise when I have a chip I will do some testing myself. |
Yes I always send 3 bytes and as far as I can see there no other option. I altered baud rate but I couldn't see any difference. I used pigpioj-java which is based on netty and it works without any problems. When I looked into the library there is wait for response implemented. This approach I applied into your code (just for testing): com.pi4j.library.pigpio.PiGpioPacket:
In my tests the change resulted in the data being able to be read. Assuming this error is not caused by the MCP3208 but in the availability of the data from the socket's InputStream. In the PIGPIO documentation I couldn't find that an end character is used in communication, because I would use that to detect the end of the data together with a read timeout. Do you know if there is end character? |
I do not know if there is an end character, and prefer we not inspect for a character to know the data was received. I was looking at your change that fixed your problem. Would you please paste your code where you create the SPI device, and when you call the transfer. Thanks much |
I used for my tests this implementation:
Some explanations:
|
You create the provider as spiProvider the upper interface class rather than pigpio-spi. I will need to run your code to validate but i suspect you follow a different path than my transfer. https://github.com/Pi4J/pi4j-example-devices/blob/master/src/main/java/com/pi4j/devices/mcp3008/MCP3008.java. I need to try your code before i have a suggestion. Maybe someone following this thread has time/ideas |
I think I didn't mention it: I run it with |
I mentioned your provider create using the parent class. My code does not enter that function you were modifying for a fix. I ran your code and the transfer runs spi class functions prior to the PigpioSpi class. My implementation directly enters the Pigpio classes. I would suggest you try using the provider create as pigpio-spi as I do in that example. Please let me know what happens. Tom |
I changed my test implementation to:
The result is the same:
Let me know if I removed some essential parts from your example. |
I received an MCP3208 to test. I ran your original example to see it returned 0 most the time. I changed your code a bit in the SPI creation, see below. The chip vdd is 3.3v. Now with the vref 3.3 v. Grounding channel 0 the reading is zero, connecting channel 0 to 3.3v the reading is 4093 2024-12-01 20:27:33:673 -0600 [main] TRACE com.pi4j.library.pigpio.impl.PiGpioNativeImpl - [SPI::OPEN] -> Open SPI Channel [0] at Baud Rate [1000000]; Flags=[0] Your first example modified by me. Commented out your creation and added mine, see the use of Pi4J Context, and I did not test the manner in which you created the provider, I used the mechanism I usually use. package com.pi4j.test.devices.dht22;
import com.pi4j.Pi4J;
import com.pi4j.context.Context;
import com.pi4j.io.spi.Spi;
import com.pi4j.io.spi.SpiChipSelect;
import com.pi4j.io.spi.SpiMode;
import com.pi4j.io.spi.SpiProvider;
//import com.pi4j.plugin.pigpio.*;
//import com.pi4j.plugin.pigpio.provider.spi.PiGpioSpiProvider;
import java.nio.ByteBuffer;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import com.pi4j.plugin.pigpio.provider.spi.PiGpioSpiProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class Pi4jTest {
private static final Logger logger = LoggerFactory.getLogger(Pi4jTest.class);
public static void main(String[] args) throws InterruptedException {
Context pi4JContext = Pi4J.newAutoContext();
/* SpiProvider spiProvider = pi4JContext.provider(PiGpioSpiProvider.class);
Spi spi = spiProvider.create(Spi.newConfigBuilder(pi4JContext)
.id("my-spi-device")
.name("My SPI Device")
.address(0)
.baud(2 * Spi.DEFAULT_BAUD)
.build());*/
var spiConfig = Spi.newConfigBuilder(pi4JContext)
.id("SPI" + 0 + "CE " +0)
.name("A/D converter")
.bus(0)
.chipSelect(SpiChipSelect.CS_0)
.flags(0b0000000000000000000000L)
.baud(Spi.DEFAULT_BAUD)
.mode(SpiMode.MODE_0)
.provider("pigpio-spi")
.build();
var spi = pi4JContext.create(spiConfig);
final SpiReader spiReader = new SpiReader(spi);
ExecutorService executor = Executors.newSingleThreadExecutor();//newFixedThreadPool(10);
for (int i = 0; i < 60; i++) {
executor.submit(new Callable<Object>() {
@Override
public Object call() throws Exception {
return spiReader.read(0);
}
});
Thread.sleep(1000);
}
executor.shutdown();
pi4JContext.shutdown();
}
private static class SpiReader {
private final Spi spi;
public SpiReader(Spi spi) {
this.spi = spi;
}
public synchronized Object read(int channel) {
byte[] rxBuffer = new byte[]{-1, -1, -1};
ByteBuffer readBuffer = ByteBuffer.allocate(3);
spi.transfer(createWriteBuffer(channel), readBuffer, 3);
logData(readBuffer.array());
return readBuffer;
}
private ByteBuffer createWriteBuffer(int channel) {
return ByteBuffer.wrap(createWriteBytes(channel));
}
private byte[] createWriteBytes(int channel) {
return new byte[]{
(byte) (0b00000110 | ((channel & 0x0007) >> 2)), // first byte, start bit
(byte) (((channel & 0x0007) << 6)), // second byte transmitted -> (SGL/DIF = 1, D2=D1=D0=0)
(byte) 0b00000000 // third byte transmitted....don't care
};
}
private void logData(byte[] result) {
int value = ((result[1] & 0x0f) << 8);
value |= (result[2] & 0xff);
logger.info("received value: {}", (value & 0x0fff));
}
}
} |
It looks like that your way of configuration results in less errors but it is present:
I don't if the difference comes from different java versions: I realized the error on a Raspberry PI4: |
At the moment I am using the version 2.7.0 of your great library with raspberry pi and pigio.
My implementation reads the data from MCP3208:
If it was successful the logging looks like (three bytes sent, three bytes received):
But something something different happens (first transfer return 0 bytes, second transfer return 6 bytes):
At the moment I don't see any possibility to handle it in my implementation because I expect three bytes and the readBuffer.postion is three as well as spi.transfer returns three.
If I look into com.pi4j.library.pigpio.impl.PiGpioSocketImpl.spiXfer I wonder if
int actual = rx.result();
is really correct or if it should beint actual = rx.dataLength();
.Is the there a relation to #16?
What do you think is the best solution to get this issue solved?
The text was updated successfully, but these errors were encountered: