SPI on Arduino with HID reader - arduino

I'm building a project that uses an HID OEM75 as the access point for a locking mechanism. We're doing our control through an Arduino Duemilanove (ATmega328). We're working with SPI for the security and (apparently) support. (I realize that any RFID chip has pretty weak security.)
I'm currently struggling with receiving bytes via SPI from the card reader.
The card reader is in autonomous read mode, meaning it reads a card, sends a signal to the Arduino (via a card present line, separate from SPI), which tells the Arduino to pull the Slave Select line high to activate the transfer cycle from the card reader. This is where I run into trouble, I can't understand how I can get the Arduino to simply read the bytes coming in from the card reader without sending any command bytes to the card reader?
The default command structure, SPI.transfer(0x00), sends a byte (in this case the dummy byte 0x00) and then accepts a byte from the source, but because our source is operating autonomously, it won't accept the dummy byte (and that will actually mess up its operation).
To word it simply: how can we accept a string of bytes from the slave source without sending bytes from the Master Source, using Arduino's SPI library?

If I am not wrong, using the SPI bus as a master is like shifting a dummy byte to the slave while reading the incoming byte in reverse.
USB HID Host driver for Windows from embedded24.net

Well it's a little late, but hey, it'll help someone out there.
First off:
which tells the Arduino to pull the Slave Select line high to activate
the transfer cycle from the card reader.
This is SPI, you pull the Slave Select low to activate the slave, not high. You put it high to tell it to shut up while others are talking.
I can't understand how I can get the Arduino to simply read the bytes
coming in from the card reader without sending any command bytes to
the card reader?
That's because you don't. In SPI, the master (which the arduino is set up as and the SPI.h library assumes) initiates communication. It sends out data on the MOSI line and the slave responds on the MISO line. If you have nothing to say to the slave, just send 0xFF or whatever dummy bytes and then check what came in on the MISO. On the arduino, I believe that gets stored in the SPDR, SPI data register. Or use whatever the spi library gives you.
but because our source is operating autonomously, it won't accept the
dummy byte (and that will actually mess up its operation).
If the case is that you really can't send data to the SPI slave device without it screwing up, then it's not actually implementing SPI, and the arduino SPI library won't help you. You'll have to hack out your own solution. The SPI standard is actually pretty loose and all sorts of people do it their own special way. Which is vastly annoying. I've seen devices use the SS line to initiate clock synching. Which means you can't just tie it to ground to have that slave always be on.
Before you write it off though, I'd suggest investigating why it won't accept the dummy byte. You might be using "3-wire" SPI which combine MOSI and MISO and turn it from full duplex into half duplex, and you'll have to get the timing right so you don't trample everything.
When getting into the nitty gritty of SPI, an oscilloscope works wonders for seeing what actually happened vs what you think should have happened.

Related

Multi-drop bus to rs232 Convert

I have a project using MDB (multi-drop bus) for vending machine (VDM).
The VDM has a MDB-RS232.
I'm not sure if it converts 9bit - 8bit (MDB-UART).
How do I read data from VDM in my computer?
Thanks all
MDB (multi-drop bus) is 9 bit, because after the standard 8 data bits (like in standard RS232 UART communication) there is a 9th bit called "mode".
(Wikipedia on MDB: "the mode bit differentiates between ADDRESS and DATA bytes.")
But you can read such data even with regular 8-bit RS232 interfaces, e.g. a plain standard USB-to-RS232 device for PC.
Here is how:
Use 9600 baud, 8 data bits, 1 stop bit, but RS232 parity setting "Space". Make sure you receive the original character value even in case of a Parity Error indication. Any MDB address byte from your VDM will be received with a Parity Error (but still be displayed correctly). Any data byte will be displayed without error.
For sending MDB ADDRESS and DATA bytes using a standard 8-bit RS232 port, you could apply temporary parity changes: Change the parity setting to "Mark" before sending an address byte, then change back to "Space" before sending data bytes.
On Windows, you can do such tricks with our Docklight software (see Docklight and MDB). It's free for basic testing and there is also a related 9-bit example project.
On Linux / Raspberry Pi other users have successfully implemented the parity trick, too, see this stackexchange post about a MDB + Pi.
But also with RealTerm, Teraterm, Termite, Bray, YAT or any other RS232 application you should be able to read the data, as long as it handles "Space" or "Mark" parity settings correctly.
You'll need an adapter which will do all convert operations on-the-fly and in real time. If you want to emulate VMC (master), you'll need MDB-UART master adapter. If you want to emulate MDB peripheral device (such as coin changer, bill validator etc), you'll need this. For two-way "sniffing" MDB bus you'll need a combination of these devices.
Direct connection PC's RS-232 to MDB will not work due to strict MDB timings (delay between VMC command and peripheral response must not exceed 5ms, delays between POLL requests are 50-300ms in general). I mean pretty reliable functioning available for commercial purposes.

ESP8266 Webster very that passes data to serial

Hello I am trying to get my ESP to run a webserver that will accept a string of text an output that text through a the uart serial pins to my arduino I can't find out how to do it I would apreshiate it
My seyup would be
Arduino connected to the esp through serial pins the esp would start a server and my pc would open the webserver and type in a string of text that string would transmit to the arduino
I can't comment yet, so I'll put this in an answer :)
What I understand is you want a simple 'webserver' on your ESP, that listens to simple GET requests, takes the query string, and sends that over the serial line to your Arduino.
Firstly, are you capable of flashing new firmware to the ESP?
It's not hard, but as I understand your request, you will need to be able to do it.
Then you need to pick what would be your preferred approach:
Flash NodeMcu firmware, and expand the webserver lua example to do what you want.
Set up the Arduino IDE to work with the ESP (tutorials exist), and write a Arduino sketch to do what you want.
You could also use esp-open-sdk, or the official Espressif SDK, and write what you want in C, but since you sound like a beginner, the two previous options are likley a better choice, their easier.
I expect the NodeMcu/lua way might be the quickest, although if you're already familiar with the Arduino IDE that might be a better choice.
If there are details you are stuck on, expand your question, and I'll see if I can stick them in the answer.

Wire High&Low Address

With regards to Arduino EEPROM when writing and reading to certain EEPROM devices it asks for a transmission of the following format:
Wire.beginTransmission(ADDR);
Wire.write(highADDR);
Wire.write(lowADDR);
Wire.write(data);
Wire.endTransmission();
What do the high address and low address mean? Why can I not just tell it to write to the byte at address 4. Why do I need to prove a high and low?
It looks to me like you are using I2C, I am going to make that assumption and base my answer off of it. Perhaps you should clarify which EEPROM you are using.
The way I2C works is that you can have one master (your Arduino) communicate with multiple slaves (your EEPROM for example) on the same I2C bus. Since it is possible to have multiple slaves connected on the same bus, I2C protocol requires you to specify what slave device you are communicating with. This is what Wire.beginTransmission(ADDR) does. It is selecting which device it wants to initiate communication with. If you want to communicate with your EEPROM you will need to send the address of your EEPROM (you should be able to find the address in the EEPROM datasheet).
Next, you need to specify the memory location inside your EEPROM where you want to access. This is done using the two bytes highADDR and lowADDR. If for instance you wanted to access the address 0x01AB, then set highADDR to 0x01 and lowADDR to 0xAB.
The rest is fairly simple. You send your data then end the transmission.
To Summarize:
Select device to communicate with (Select your EEPROM)
Wire.beginTransmission(ADDR);
Tell your EEPROM what memory address you want to write to
Wire.write(highADDR); // Send the most significant address bits
Wire.write(lowADDR); // Send the least significant address bits
Send data to write.
Wire.write(data);
End the transmission
Wire.endTransmission();
I strongly recommend reading more about how the I2C protocol works. http://en.wikipedia.org/wiki/I%C2%B2C#Message_protocols

Arduino: Packet loss on Serial communication

I am trying connect multiple Arduino Mega Boards via their Serial pins to allow communication between the boards. I want to be able to connect an arbitrary amount of arduinos by daisy-chaning them and I want one board to be the master, taking control over the actions of the other boards. The master should be determined dynamically by the boards. I am aware that the daisy chaining method introduces delays to the communication due to the forwarding of packets, but so far I am planning on connection 4 boards at most. In the future this might increase to maybe 10 boards. My boards all have a separate power source, since they are connected to some other hardware which has its own power source.
My idea was to connect the boards in such a way, that the master would be determined by the wireing of the boards. I thought about having the "Serial" port as 'To-Master' serial port and the "Serial1" port as "To-Child" serial port. The boards send hello messages on the "To-Master" serial port and the master replies if it received such a message on the "To-Child" serial port. If no answer is received after some seconds, the board determines itself to be the master.
I wired the boards up by connecting the ground pins, and wiring RX1 of the master to TX0 of the child and TX1 of the master to RX0 of the child:
Basically my setup is working, since the boards do detect each other and exchange hello messages and replies. There is however a significant amount of packet loss or corruption which I would like to eliminate.
As a simple measure of packet verification, I begin each packet with a "magic number". The receiving board looks for this byte and only tries to read a packet after receiving this byte. Any other bytes received are simply discarded.
As it seems, it happens quite often that something is received on either serial port that does not start with the magic number and is therefore discarded. The timestamps of these events are however consistent with the timestamps of sending of the other board meaning that the packet was at least partially transmitted but somehow the magic byte got corrupted or discarded.
Is this a known problem with the arduinos serial ports?
Can it be related to my wiring?
Are there any measures I can take to ensure a save delivery of the packets?
Can it be a problem of the boards not reading the signal at the correct time (I used a baud rate of 9600)?
I also looked into I2C communication, but I did not find any resource or information if it is possible to dynamically choose the master for this type of communication. Also in the documentation it stated, that it is important that all devices share a common power source which is not possible in my scenario. However, the basic master-slave principle of this I2C conforms with my requirements, as I have a master that sends commands to all other boards. Could I2C be utilized in my case?
Thank you for your thoughts!
Here is a discussion about multi-master I2C topology of Arduinos, seems that it is supported (haven't tested it myself). - http://forum.arduino.cc/index.php/topic,13579.0.html
You can test SPI as well, here is a comparison between the two - http://components.about.com/od/Theory/a/Selecting-Between-I2c-And-Spi.htm.
Slave might be selected with generic GPIOs
I don't know any known implementation of multi-clients on top of Serial bus (usually it is intended for peer2peer communication only) - even though, your configuration seems reasonable, I would be considering other options.
BTW, from your comment about different power sources, I assume your boards are away from each-other. Have you considered very cheap ($2) RF modules, such as nRF24L01+ (http://maniacbug.wordpress.com/2011/11/02/getting-started-rf24/). THere is a library for networking those in multi-node network
Might be better off with I2C or SPI like people have suggested here.
However, to address your question directly, it is most likely wiring. I am assuming you are using cheap jumper wires to plug directly into the Arduino Headers. Noise on this connection is the most likely problem or garbled serial messages. Try implementing with twisted pair cables and connecting directly to the board.
SPI or I2C might have better error correction than your customer serial protocol. I would see the other answers for that.

Serial Transfer UART Delay

I currently have an embedded device connected to a PC through a serial port. I am having trouble with receiving data on the PC. When I use my PCI serial port card I am able to receive data right away (no delays). When I use my USB-To-Serial plug or the motherboards built in serial port I have to delay reading data (40ms for 32byte packets).
The only difference I can find between the hardware is the UART. The PCI card uses a 16650 and the plug/motherboard uses a standard 16550A. The PCI card is set to interrupt at 28 bytes and the plug is set to interrupt at 14 bytes.
I am connected at 56700 Baud (if this helps).
The delay becomes the majority of the duty cycle and really increases transfer time. (10min transfer vs 1 hour transfer).
Does anyone have an explanation for why I have to use a delay with the plug/motherboard? Can anyone suggest a possible solution to minimizing or removing this delay?
Linux has an ASYNC_LOW_LATENCY flag for the serial driver that may help. Whatever driver you're using may have something similar.
However, latency shouldn't make a difference on a bulk transfer. It should add 40 ms at the very start of the transfer and that's it, which is why drivers don't worry about it in the first place. I would recommend refactoring your transfer protocol to use a sliding window protocol, with a window size of around 100 packets, if you are doing 32-byte packets at that baud rate and latency. In other words, you only want to stop transmitting if you haven't received an ACK for the packet you sent 100 packets ago.
You'll probably find that different USB-Serial converters produce different results. We've found that the FTDI ones work well for talking with embedded devices. Some converters seem to buffer the data for a long time and/or fragment it.
I've never seen a problem with a motherboard connection - not sure what is going on there! Can you change the interrupt point for the motherboard serial port?
I have a serial to usb converter. When I hook it up to my breakout box and create a loopback I am able to send / receive at close to 1Mbps without problems. The serial port sends binary data that may be translated into ascii data.
Using .Net I set my software to fire an event on every byte (ReceivedBytesThreshold=1), though that doesn't mean it will.

Resources