Have been working on an experiment.
Using 8 LEDs (each has its own 220 ohm resistor) connected to a SN74HC595N shift register pins QA-QH (15, 1, 2, 3, 4, 5, 6, 7), have pin 16 connected to 5v rail, pin 10 connected to 5v rail, pin 8 to ground rail with 0.1 uF cap to 5v for voltage smoothing, this is on its own mini breadboard that is tethered to another minin breadboard for power. The other bread board has the ATTiny85 that is connected to VCC on pin 8, ground on pin 4 and has 0.1 uF and 10 uF caps bridged from pin 4 to pin 8. On pin 1/reset/PB5 there is a 10k ohm resistor to 5v rail and connected to Uno as ISP pin 10, Pin 2/PB3 is set to RX and connected to TFLuna pin3/TX, pin 3/PB4 is set TX and connected to TFLuna pin 2/RX through 4.7 k ohm resistor with 1 k ohm resistor to ground rail, pin 5/PB0 is connected to Uno as ISP on pin 11 and shift register pin 14/DS/SER, pin 6/PB1 is connected to ISP pin 12 and register pin 11/SH_CP/SRCLK, pin 7/PB2 is connected to ISP pin 13 and register pin 12/ST_CP/RCLK. TFLuna is connected to ATTiny as mentioned above and to 5v rail and ground rail with 10 uF cap bridged. Uno 5v and ground is connected to 5v and ground rails.
Had started developing this with Uno as dev board. Wrote code to detect distance with TFLuna and light LEDs in a pattern of 1 at a time lighting up and then off 1 at a time. It worked well, adjusted timing to get a smooth transition from slower to faster with approaching object. Then transitioned to stand alone ATMega328P on breadboard to do the same. It took some time to get it to function, but it went well.
Now at the stage of taking it to ATTiny. This has been a tail chasing adventure. Have been utilizing AI to assist development. Have verified connections, power, grounds, TFLuna signal, chip receiving signal capability, chip transmitting signal capability, register receiving signal capability, register control of LEDs, ISP programming capability.
Yet the code to run the sequence does not function. Have changed TFLuna baud rate to 9600 (verified) and ensured the same setting in ISP. Through AI suggestions have attempted many code variations to address timing and buffer overload.
Could someone look at the latest code and advise please? I have been working at this for a week, and most if it is getting scrambled in my head.
Thank you to anyone that reads this far.
Oops! forgot the code...
#define LUNA_RX_PIN 3 // Physical Pin 2 (PB3) -> TF-Luna TX
#define DATA_PIN 0 // Physical Pin 5 (PB0) -> SN74HC595 Pin 14 (DS)
#define CLOCK_PIN 1 // Physical Pin 6 (PB1) -> SN74HC595 Pin 11 (SH_CP)
#define LATCH_PIN 2 // Physical Pin 7 (PB2) -> SN74HC595 Pin 12 (ST_CP)
const byte animationSequence[16] = {
0b00000001, 0b00000011, 0b00000111, 0b00001111,
0b00011111, 0b00111111, 0b01111111, 0b11111111,
0b01111111, 0b00111111, 0b00011111, 0b00001111,
0b00000111, 0b00000011, 0b00000001, 0b00000000
};
void setup() {
pinMode(DATA_PIN, OUTPUT);
pinMode(CLOCK_PIN, OUTPUT);
pinMode(LATCH_PIN, OUTPUT);
pinMode(LUNA_RX_PIN, INPUT_PULLUP);
updateRegister(0b00000000);
}
void loop() {
uint32_t silenceCounter = 0;
while (silenceCounter < 2000) {
if (digitalRead(LUNA_RX_PIN) == LOW) {
silenceCounter = 0;
} else {
silenceCounter++;
delayMicroseconds(1);
}
}
if (readByteRaw() == 0x59) {
if (readByteRaw() == 0x59) {
byte distanceLow = readByteRaw();
byte distanceHigh = readByteRaw();
int distance = distanceLow + (distanceHigh << 8);
for (int i = 0; i < 5; i++) {
readByteRaw();
}
if (distance >= 10 && distance <= 300) {
int stepDelayMs = calculateSimpleDelay(distance);
for (int i = 0; i < 16; i++) {
updateRegister(animationSequence[i]);
for (int m = 0; m < stepDelayMs; m++) {
delayMicroseconds(1000);
}
}
}
}
}
}
byte readByteRaw() {
uint32_t safetyTimeout = 0;
while (digitalRead(LUNA_RX_PIN) == HIGH) {
safetyTimeout++;
if (safetyTimeout > 20000) return 0;
delayMicroseconds(1);
}
delayMicroseconds(156);
byte result = 0;
for (byte b = 0; b < 8; b++) {
if (digitalRead(LUNA_RX_PIN) == HIGH) {
result |= (1 << b);
}
delayMicroseconds(104);
}
return result;
}
void updateRegister(byte data) {
digitalWrite(LATCH_PIN, LOW);
// FLIPPED TO LSBFIRST: Matches standard Q0-Q7 hardware wiring arrays
shiftOut(DATA_PIN, CLOCK_PIN, LSBFIRST, data);
digitalWrite(LATCH_PIN, HIGH);
}
int calculateSimpleDelay(int distance) {
if (distance < 10) distance = 10;
if (distance > 300) distance = 300;
float normalized = (float)(distance - 10) / 290.0;
return 30 + (int)(220.0 * (normalized * normalized));
}
You aren't shifting "result" when you receive zeros...
This routine may also be subject to timing issues, since digitalRead() can be slow, and delayMicroseconds may not be as accurate as you hope.
Which "core" are you using? You might want to consider one of the newer chips, although that would mean dealing with SOIC rather than DIP. They have hardware UARTs, and are cheaper.
And what is a TFLuna?
What speed is your ATtiny85 clocked at?
Have you checked that the factory default OSCCAL value is close enough to be able to decode a complete byte without slipping a bit?
Does the TFLuna, whatever it is, allow sufficient time between bytes for the ATtiny85 to do the other things you're asking it to do without slipping bits?
What purpose does this code serve?
for (int i = 0; i < 5; i++) {
readByteRaw();
}
Time of Flight Lidar.
Yes, it's unhelpful to have to look it up.
Follow these procedures:
1. Perform the experiment of Section-19.2 of the attaced file to establish that your ATtiny85 chip is OK, and you can program it using Arduino as ISP Programmer (Fig-1).
Figure-1:
2. After that program ATtiny85 to operate your 74HC595 shift register (Fig-2) using bit-bang and not using SPI Port (why? See 3.). During ATtiny85 programming, disconnect the MISO (PB1) line from 74HC595.
Fig-2:
3. After that connect your TFLuna device with ATtiny85 using I2C bus and NOT UART Port as ATtiny85 has no hardware UART Port. I am not sure if you can operate Software UART Port of ATtiny85 using SoftwareSerial.h Library though STX works. During ATtiny85 programming, disconnect the MISO (PB1) line from 74HC595.
Ch-16 ATtiny85 MCULec.pdf (959.2 KB)
Thank you for response :^)
To answer "What is TFLuna?" It is Lidar sensor to detect movement within a specific range.
OSCCAL had been addressed during AI session of tail chasing.
That for (int i = 0; i < 5; i++) loop simply acts as a cleaner—it sweeps those 5 unwanted pieces of data off the counter so that the wire is completely clear and ready for the next brand-new packet to arrive. Or at least that is what Gemini tells me.
I am not that advanced in coding yet, using AI to help me through. Though it has been what seems to be a tail chasing event.
As always, the problem inherent in trying to use an AI to do something you don't know how to do yourself is that you won't know when it's just making stuff up, or even flat out lying to you. AI is not helping you. It is holding you back and wasting your time.
There is no royal road to learning. But it's your time. Good luck!
PS it's generally a good idea to answer all questions put to you. Not doing so is a good way of being shown the door.
Example is a way of learning new things. In post #2, I have provided OP an example in the attached file which he is reluctant to perform
Thank you for your suggestions and advise!
My coding skills are not very advanced, and this is a little confusing for me, my apology for my ignorance in this.When you state I am not shifting result when receiving zeros... can you explain this in a way that I might understand it better? I think it is that the signal from TFLuna is being misread?
As far as which core, that is the ATTinyCore I am assuming? That would be the damellis core package (by David A. Mellis) and AI is telling me this is the issue now. It is recommending the Spence Konde ATTinyCore. I am getting to install the Spence Konde ATTinyCore to go to File > Preferences and enter: http://drazzy.com/package_drazzy.com_index.json in the dialog box: Additional Boards Manager URLs: click OK, then go to Tools > Board > Boards Manager > and search ATTinyCore, that search returns nothing. AI has directed to search GitHub repository, that returns nothing, rebooted IDE, still nothing. The Spence konde ATTinyCore missing and ATTiny not showing under Tools > Board pop out menu is a big clue. That explains why (perhaps) this is not functioning.
AI has helped in getting the Konde ATTinyCore back. It instructed to create a folder in Arduino folder named hardware, then download the file direct, place it in that folder, which put the ATTinyCore back into the Boards popout menu. Will give this a try... see what happens. Ai didn't catch the missing Core, you pointed me in that direction, THANK YOU!
OK, thank you for the advise. Will heed that. Have been on this journey to learn the code, have been hitting brick walls for quite some time. Understanding the code is like a foreign language that makes no sense. I understand that AI makes mistakes and sometimes (usually) guesses at the next best answer. Have caught it doing that. It is my fault for allowing myself to drift down that path.
I am attempting to work through this. My understanding is limited, though I will do my best to learn from your advise.
1 thing that looks wrong though, in fig. 1 it shows connecting Uno 5v to ATTiny Gnd physical pin 4 and Uno ground to ATTiny VCC physical pin 8. To me that sounds reversed, is my perception incorrect here? Or am I stuck in my automotive ways that power is not to be connected to ground?
Otherwise this is how I have Uno connected to program (except for the resistor and LED on PB4). Have already st ATTiny to run at 8 mHz internal clock speed.
Programming to use bit-bang will require some research (I do not understand what that is).
Will need to come back to this tomorrow, have other obligations for right now.
Thank you to all, will do my best to learn this the correct way. Was advised to use Codedex for learning... any thoughts?
Ok, so I at least have something going my way... lol
Will work at this tomorrow, will have more time then.
Thanks again.
Your readByteRaw() function is broken.
Unless you're really intent on understanding details at that level, you should probably just replace it with a known-working version, perhaps just the "softwareSerial" library that normally comes with an Arduino core. (SoftwareSerial will want a "transmit" pin as well, which I guess you don't need - you can use any unused pin for that (and even re-use it as a digital output later, if you wish.)
There are an unfortunate number of cores that include the tiny85, most of which have been neglected for a long time. (Mellis: no longer involved, afaik. Digistump: moved on to other things. Etc.)
At this point, you should probably use TinyCore - a new Arduino core for classic ATtiny chips
Thank you for explaining. At this point I am attempting to understand more than just the basics. I would like to learn the complex code as well, but you are probably on point with the alternatives for now.
I went back to my IDE and found that I had lost (somehow) the Spence Konde ATTinyCore that I had downloaded. Got it back in the IDE.
I will research your suggestions and try adding them in.
Here is commented version, with comments, that ought to be closer to working (not actually tested...)
byte readByteRaw() {
/*
* Read a UART-style byte from a digital Pin.
* bit pattern is "iiiii L 0123 4567 S iiii L...", where:
* i is the idle state of the line (HIGH)
* L is a LOW "Start Bit" - indicates that data is coming.
* 0-7 are the data bits, either zeros or ones.
* S is a HIGH "Stop bit" that indicates the end of the transmission.
* Each of the bits is about 104us long (at 9600bps)
*/
const int BITTIME = 104; // one bit = 104us
byte thisBit; // the currently read bit.
byte result; // The byte we've collected so far.
/*
* First, we'll wait about 20ms to see the beginning of the start bit.
* If no start is seen, we'll give up and return 0
*/
uint32_t safetyTimeout = 0;
while (digitalRead(LUNA_RX_PIN) == HIGH) {
safetyTimeout++;
if (safetyTimeout > 20000) {
return 0;
}
delayMicroseconds(1);
}
/*
* Having seen the begining of the start bit, wait 1.5 bit times to put
* us approximately at the middle of the first data bit... (3/2 == 1.5)
*/
delayMicroseconds((BITTIME*3)/2);
for (byte b = 0; b < 8; b++) {
/*
* read 8 bits, waiting BITTIME between each one (should take us
* to the middle of the next bit.)
*/
if (digitalRead(LUNA_RX_PIN) == HIGH) {
thisBit = 1;
} else {
thisBit = 0;
}
/*
* shift the byte we are collecting, and OR in the current bit.
*/
result = (result << 1) | thisBit;
delayMicroseconds(104); // wait for next bit.
}
return result;
/*
* Note that by waiting 104us after the 8th bit, the input should now
* be in the middle of stop bit; ie ready for the next byte...
*/
}
Please show a schematic of those 450 or so words. Carefully hand-drawn would suffice. Or high resolution photos.
Reviewing the code given, in the section:
* First, we'll wait about 20ms to see the beginning of the start bit.
* If no start is seen, we'll give up and return 0
*/
uint32_t safetyTimeout = 0;
while (digitalRead(LUNA_RX_PIN) == HIGH) {
safetyTimeout++;
if (safetyTimeout > 20000) {
return 0;
}
from my understanding 20000 = 20 seconds. Am I off base here? Or should it be 20 for 20 ms?
Hi,
It is my perception this is a snippet of code to be placed (possibly) into a sketch I posted earlier in this thread. If my understanding is correct, it addresses readByteRaw() function. I have not prpvided a schematic of my circuit here, yet there is a detailed description in my original post.
Thank you for your interest :^)


