0.1.1 shiftOutSlow

This commit is contained in:
rob tillaart 2021-08-16 19:25:37 +02:00
parent 50c8a2e0f7
commit 348f6cceff
7 changed files with 184 additions and 33 deletions

View File

@ -12,40 +12,54 @@ A library for shiftInSlow also exist.
## Description
ShiftOutSlow is an experimental library that has a build in delay (in microseconds) that allows tuning the time per bit.
ShiftOutSlow is an experimental library that has a build in delay (in microseconds) that allows tuning the time per bit.
This allows one to improve reliability e.g. when using longer lines.
The datapin and clockpin are set in the constructor, the delay is settable per byte send to be able to optimize runtime.
The data pin and clock pin are set in the constructor, the delay can be set per byte send to be able to optimize runtime.
ShiftOutSlow implements the print interface.
## Performance
The performance of **write()** with a delay of 0 microseconds is slower than the default Arduino
**shiftOut()** due to some overhead.
The performance of **write()** with a delay of 0 microseconds is slower than the default Arduino
**shiftOut()** due to some overhead.
The delay requested is split in two (expect rounding errors) to have "nice" looking pulses.
The delay requested is divided by two to minimize disruption of the duty cycle of the clock pulse,
resulting in "better" pulses.
## Interface
The interface exists of the following functions:
- **ShiftOutSlow(datapin, clockpin, bitorder = LSBFIRST)** constructor.
- **size_t write(uint8_t data)** writes a new value
- **uint8_t lastWritten()** returns last value written
- **void setDelay(uint16_t microseconds)** set delay per bit from 0 .. 65535 microseconds.
- **ShiftOutSlow(dataPin, clockPin, bitOrder = LSBFIRST)** constructor.
- **size_t write(uint8_t data)** writes a new value. Returns the bytes written.
- **size_t write(const uint8_t \*buffer, size_t size)** writes an array of size over shift out. Uses **write(uint8_t)** so expect about equal performance. Returns the bytes written.
- **uint8_t lastWritten()** returns last value written.
- **void setDelay(uint16_t microSeconds)** set delay per bit from 0 .. 65535 microseconds.
Note that the delay is not the time per bit but an additional time per bit.
Note: the delay can be set runtime per write / print call.
- **uint16_t getDelay()** returns the set delay in microseconds.
- **bool setBitOrder(bitOrder)** set LSBFIRST or MSBFIRST. Returns false for other values.
- **uint8_t getBitOrder(void)** returns LSBFIRST or MSBFIRST
Note: bitorder can be changed runtime per write / print call.
- **uint8_t getBitOrder(void)** returns LSBFIRST or MSBFIRST (typical 0 and 1).
## Notes
### Print interface
- to be tested
As this library implements the print interface one can use:
- **size_t print(any)** print any data type.
- **size_t println(any)** print any data type followed by a newline "\n".
## Operation
See examples
See examples.
## Future
- Add a select pin to be more SPI alike?

View File

@ -1,11 +1,16 @@
//
// FILE: ShiftOutSlow.cpp
// AUTHOR: Rob Tillaart
// VERSION: 0.1.0
// VERSION: 0.1.1
// PURPOSE: Arduino library for shiftOut with build-in delay
// DATE: 2021-05-11
// URL: https://github.com/RobTillaart/ShiftOutSlow
// HISTORY
// 0.1.0 2021-05-11 initial version
// 0.1.1 2021-08-16 add write(buffer, size) = print interface.
// improve delay math; update readme.md
#include "ShiftOutSlow.h"
@ -13,22 +18,24 @@
ShiftOutSlow::ShiftOutSlow(const uint8_t dataPin, const uint8_t clockPin, const uint8_t bitOrder)
{
_clockPin = clockPin;
_dataPin = dataPin;
_dataPin = dataPin;
_bitOrder = bitOrder;
_value = 0;
pinMode(_dataPin, OUTPUT);
pinMode(_clockPin, OUTPUT);
// https://www.arduino.cc/reference/en/language/functions/advanced-io/shiftin/
digitalWrite(_clockPin, LOW); // assume rising pulses from clock
digitalWrite(_clockPin, LOW); // assume rising pulses from clock
}
size_t ShiftOutSlow::write(const uint8_t data)
{
uint8_t val = data;
uint8_t val = data;
uint16_t d1 = _delay/2;
uint16_t d2 = _delay - d1;
for (uint8_t i = 0; i < 8; ++i)
{
if (_delay > 0) delayMicroseconds(_delay/2);
if (d1) delayMicroseconds(d1);
if (_bitOrder == LSBFIRST) {
digitalWrite(_dataPin, val & 0x01);
val >>= 1;
@ -37,7 +44,7 @@ size_t ShiftOutSlow::write(const uint8_t data)
val <<= 1;
}
digitalWrite(_clockPin, HIGH);
if (_delay > 0) delayMicroseconds(_delay/2);
if (d2) delayMicroseconds(d2);
yield();
digitalWrite(_clockPin, LOW);
}
@ -46,11 +53,21 @@ size_t ShiftOutSlow::write(const uint8_t data)
}
size_t ShiftOutSlow::write(const uint8_t *buffer, size_t size)
{
for (uint8_t i = 0; i < size; ++i)
{
write(buffer[i]);
}
return size;
}
bool ShiftOutSlow::setBitOrder(const uint8_t bitOrder)
{
if ((bitOrder == LSBFIRST) || (bitOrder == MSBFIRST))
{
_bitOrder = bitOrder;
_bitOrder = bitOrder;
return true;
};
return false;

View File

@ -2,7 +2,7 @@
//
// FILE: ShiftOutSlow.h
// AUTHOR: Rob Tillaart
// VERSION: 0.1.0
// VERSION: 0.1.1
// PURPOSE: Arduino library for shiftOut with build-in delay
// DATE: 2021-05-11
// URL: https://github.com/RobTillaart/ShiftOutSlow
@ -12,7 +12,7 @@
#include "Arduino.h"
#define SHIFTOUTSLOW_LIB_VERSION (F("0.1.0"))
#define SHIFTOUTSLOW_LIB_VERSION (F("0.1.1"))
class ShiftOutSlow : public Print
@ -21,13 +21,17 @@ public:
// bitorder = { LSBFIRST, MSBFIRST };
ShiftOutSlow(const uint8_t dataPin, const uint8_t clockPin, const uint8_t bitOrder = LSBFIRST);
size_t write(const uint8_t data);
// PRINT INTERFACE
virtual size_t write(const uint8_t data) override;
virtual size_t write(const uint8_t *buffer, size_t size) override;
uint8_t lastWritten(void) { return _value; };
bool setBitOrder(const uint8_t bitOrder);
uint8_t getBitOrder(void) { return _bitOrder; };
void setDelay(uint16_t d) { _delay = d; };
// microSeconds = 0..65535
void setDelay(uint16_t microSeconds) { _delay = microSeconds; };
uint16_t getDelay() { return _delay; };

View File

@ -0,0 +1,98 @@
//
// FILE: shiftOutSlow_print.ino
// AUTHOR: Rob Tillaart
// VERSION: 0.1.0
// PURPOSE: test sketch for print interface
// URL: https://github.com/RobTillaart/ShiftOutSlow
//
#include "ShiftOutSlow.h"
ShiftOutSlow SOS(12, 13, LSBFIRST);
volatile int x = 0;
void setup()
{
Serial.begin(115200);
Serial.println(__FILE__);
Serial.println(SHIFTOUTSLOW_LIB_VERSION);
Serial.println("\nwrite(byte)");
Serial.println("delay\tus/byte");
delay(10); // extra time to flush serial buffer
for (uint16_t d = 0; d < 100; d += 10)
{
SOS.setDelay(d);
uint32_t start = micros();
x = SOS.write(0x55);
uint32_t stop = micros();
float duration = stop - start;
Serial.print(d);
Serial.print("\t");
Serial.println(duration / x, 2);
delay(10);
}
char str[24] = "hello world!";
Serial.println("\nwrite(buffer, size)");
Serial.println("delay\tus/byte");
delay(10);
for (uint16_t d = 0; d < 100; d += 10)
{
SOS.setDelay(d);
uint32_t start = micros();
x = SOS.write((const uint8_t*) str, 12);
uint32_t stop = micros();
float duration = stop - start;
Serial.print(d);
Serial.print("\t");
Serial.println(duration / x, 2);
delay(10);
}
Serial.println("\nprint(str)");
Serial.println("delay\tus/byte");
delay(10);
for (uint16_t d = 0; d < 100; d += 10)
{
SOS.setDelay(d);
uint32_t start = micros();
x = SOS.print(str);
uint32_t stop = micros();
float duration = stop - start;
Serial.print(d);
Serial.print("\t");
Serial.println(duration / x, 2);
delay(10);
}
Serial.println("\nprintln(str)");
Serial.println("delay\tus/byte");
delay(10);
for (uint16_t d = 0; d < 100; d += 10)
{
SOS.setDelay(d);
uint32_t start = micros();
x = SOS.println(str);
uint32_t stop = micros();
float duration = stop - start;
Serial.print(d);
Serial.print("\t");
Serial.println(duration / x, 2);
delay(10);
}
Serial.println(LSBFIRST);
Serial.println(MSBFIRST);
Serial.println("done...");
}
void loop()
{
}
// -- END OF FILE --

View File

@ -1,7 +1,7 @@
{
"name": "ShiftOutSlow",
"keywords": "Shift, shiftOut, out, serial, slow, 74HC595",
"description": "Arduino library for shiftOut with build-in delay - e.g. for 74HC595",
"description": "Arduino library for shiftOut with build-in delay - e.g. for 74HC595.\nImplements the print interface.",
"authors":
[
{
@ -15,7 +15,7 @@
"type": "git",
"url": "https://github.com/RobTillaart/ShiftOutSlow.git"
},
"version": "0.1.0",
"version": "0.1.1",
"license": "MIT",
"frameworks": "arduino",
"platforms": "*"

View File

@ -1,9 +1,9 @@
name=ShiftOutSlow
version=0.1.0
version=0.1.1
author=Rob Tillaart <rob.tillaart@gmail.com>
maintainer=Rob Tillaart <rob.tillaart@gmail.com>
sentence=Arduino library for shiftOut with build-in delay - e.g. for 74HC165
paragraph=
paragraph=implements the print interface
category=Signal Input/Output
url=https://github.com/RobTillaart/ShiftOutSlow
architectures=*

View File

@ -31,7 +31,7 @@
// PATCH FOR DUE & ZERO FOR UNIT TEST - https://github.com/Arduino-CI/arduino_ci/issues/252
#if defined(ARDUINO_ARCH_SAM) || defined(ARDUINO_ARCH_SAMD)
// - due # ARDUINO_ARCH_SAM does not support shiftIn apparently
// - zero # ARDUINO_ARCH_SAMD
// - zero # ARDUINO_ARCH_SAMD
#endif
@ -52,7 +52,7 @@ unittest(test_constructor)
assertEqual(1, SOS.write(65));
assertEqual(65, SOS.lastWritten());
assertEqual(LSBFIRST, SOS.getBitOrder());
SOS.setBitOrder(MSBFIRST);
assertEqual(MSBFIRST, SOS.getBitOrder());
}
@ -66,7 +66,7 @@ unittest(test_constructor_LSB)
assertEqual(1, SOS.write(65));
assertEqual(65, SOS.lastWritten());
assertEqual(LSBFIRST, SOS.getBitOrder());
SOS.setBitOrder(MSBFIRST);
assertEqual(MSBFIRST, SOS.getBitOrder());
}
@ -80,7 +80,7 @@ unittest(test_constructor_MSB)
assertEqual(1, SOS.write(65));
assertEqual(65, SOS.lastWritten());
assertEqual(MSBFIRST, SOS.getBitOrder());
SOS.setBitOrder(LSBFIRST);
assertEqual(LSBFIRST, SOS.getBitOrder());
}
@ -98,6 +98,24 @@ unittest(test_setDelay)
}
}
unittest(test_print_interface)
{
ShiftOutSlow SOS(12, 13);
fprintf(stderr, "VERSION:\t%s\n", SHIFTOUTSLOW_LIB_VERSION);
int x = SOS.print("hello world");
assertEqual(11, x);
int y = SOS.println("hello world");
assertEqual(13, y);
char str[20] = "hello world";
// casting needed for CI environment.
int z = SOS.write((const uint8_t*) str, 8);
assertEqual(8, z);
}
unittest_main()
// --------