Implement a sharp right turn using atmega8 for line follower - avr

I am new to AVR programming, and I am trying to implement a sharp right turn using atmega8. I was able to implement the straight line path but cannot implement a sharp right turn. Here is my code:
`#include <avr/io.h>
#include<util/delay.h>
int main(void)
{
DDRC=0b00000000;
DDRB=0b11111111;
int count=1,right=1;
while(1)
{
if((PINC&=0b00011111)==0b00000000)
{
PORTB=0b00000110;
}
else if((PINC&=0b00011111)==0b00001110)
{
PORTB=0&00100111;
}
else if((PINC&=0b00011111)==0b00001100)
{
PORTB=0b00000111;
}
else if((PINC&=0b00011111)==0b00000110)
{
PORTB=0b00100110;
}
else if((PINC&=0b00011111)==0b00001111)
{
if(count)
{
PORTB=0b0010011;
_delay_ms(200);
count--;
}
else if(((PINC&=0b00011111)==0b00000110)&&~(count))
{
PORTB=0B00000111;
}
}
else if((PINC&=0b00011111)==0b00011110)
{
if(right)
{
PORTB=0b0010011;
_delay_ms(200);
right--;
}
else if(((PINC&=0b00011111)==0b00000110)&&~(right))
{
PORTB=0B00100110;
}
}
}
}
This doesn't seem to work at all for right and left turns.
Any idea where I am going wrong?

Without understanding your Program (see my Comment above) iam guessing it is because you permanently write to your PIN-regsiters in the if-clauses.
PINC&=0b00011111 means:
read PINC-value
binary AND it with 0b00011111
write the result back to PINC
Depending on which AVR your code is running you toggle the output by writing a 1 to a PINX-register bit. If DDR is configured to input you toggle the pullups. This is true for the newer AVR-cores. For the old one its undefined behavior to write to the PIN-registers as they are defined as read-only.

Related

Unity freezes because of script, but i don't know whats wrong with said script

Bear with me, I'm pretty new to unity.
As the title suggests, the game engine freezes when this script is attached to the main camera.
public class leftright : MonoBehaviour {
public float boundaries = 3f;
void Update () {
while (Input.GetAxis("Mouse X") < boundaries && Input.GetAxis ("Mouse X") > -boundaries) {
this.transform.Rotate(0, Input.GetAxis("Mouse X"), 0);
}
}
}
I don't think this script makes an infinite loop, and I can't detect any problem with it.
the log text is here, and the project is here
While(true) {
//do stuff
}
The conditional you're using in your while statement cannot (and will not) ever change from true to false based on the contents of the loop, therefor it will run forever.
Update() is already a loop, treat it like one.
void Update () {
if(Input.GetAxis("Mouse X") < boundaries && Input.GetAxis ("Mouse X") > -boundaries) {
this.transform.Rotate(0, Input.GetAxis("Mouse X"), 0);
}
}

3-wheel robot not moving back or left using voice commands

I am working on 3-wheel robot. I want to move my robot front, back, right, left using voice commands. I am using arduino electronics as my mobile app. By using that app I want to control my robot. I am using an arduino uno board and L293D motor driver. Below is my code for 3-wheel robot:
String readvoice;
void setup() {
//BT.begin(9600);
Serial.begin(9600);
pinMode(7, OUTPUT);
digitalWrite(7, HIGH);
}
//-----------------------------------------------------------------------//
void loop() {
while (Serial.available()) { //Check if there is an available byte to read
delay(10); //Delay added to make thing stable
char c = Serial.read(); //Conduct a serial read
readvoice += c; //build the string- "forward", "reverse", "left" and "right"
}
if (readvoice.length() > 0) {
Serial.println(readvoice);
if (readvoice == "go")
{
//Serial.println("front"); //Writing values to motor driver
digitalWrite(4,HIGH);
digitalWrite(5,LOW);
digitalWrite(7,LOW);
digitalWrite(6,HIGH);
}
if (readvoice == "left")
{
//Serial.println("left");
digitalWrite(4,HIGH);
digitalWrite(5,LOW);
digitalWrite(7,HIGH);
digitalWrite(6,LOW);
}
if(readvoice == "right")
{
//Serial.println("right");
digitalWrite(4,LOW);
digitalWrite(5,HIGH);
digitalWrite(7,LOW);
digitalWrite(6,HIGH);
}
if (readvoice == "back")
{
//Serial.println("back");
digitalWrite(4,LOW);
digitalWrite(5,HIGH);
digitalWrite(7,HIGH);
digitalWrite(6,LOW);
}
if (readvoice == "stop")
{
//Serial.println("stop");
digitalWrite(4,LOW);
digitalWrite(5,LOW);
digitalWrite(7,LOW);
digitalWrite(6,LOW);
}
readvoice = "";
}
}
I kept all the connections correctly, but my robot is able to move only right and front. I am not able to run my robot either left or back. Is there any problem in the code? Or any problem with hardware. If i had any problem with hardware, my robot should not move front or right either, but it is moving. Any idea what is wrong with back and left?

Adding a condition to Amibroker code

This is my Amibroker code for a 2 bar swing chart, I need to add a condition that if price falls below the previous swing low in one bar, then to treat it as a two bar move. The problem I have is, holding the last swing low price variable to check against todays low. I have commented the problem lines in caps. What I have I thought would work but the condition is not showing up on the swing chart. Can someone tell me what I am doing wrong.Thanks.
_SECTION_BEGIN("2 day swing");
upBar = H>Ref(H,-1);
dnBar = L<Ref(L,-1);
HighBarPrice=LowBarPrice=Null;
inLong=inShort=upCount=dnCount=fupbar=fdnbar=0;
for( i=1; i<BarCount; i++ )
{
if(inLong==0 AND inShort==0)
{
if(upBar[i])
{
upCount=upCount+1;
if(upCount==2)
{
fupbar[i] = 1;
inLong=1;
dnCount=0;
}
}
if(dnBar[i])
{
dnCount=dnCount+1;
if(dnCount==2)
{
fdnbar[i] = 1;
inShort=1;
upCount=0;
}
}
if(inLong==1)
{
if(dnBar[i])
{
dnCount=dnCount+1;
if(L[i]<LowBarPrice) {dnCount=2;} //THIS IS THE PROBLEM
if(dnCount==2)
{
fdnbar[i]=1;
inShort=1;
if(upBar[i])
{
upCount=1;
}
else
{
upCount=0;
}
continue;
}
}
if(upBar[i]) {HighBarPrice=H[i];}
if(upBar[i] AND NOT dnBar[i]){ dnCount=0;}
}
if(inShort==1)
{
if(upBar[i])
{
upCount=upCount+1;
if(H[i]>HighBarPrice) {upCount=2;}
if(upCount==2)
{
fupbar[i]=1;
inLong=1;
if(dnBar[i])
{
dnCount=1;
}
else
{
dnCount=0;
}
continue;
}
}
if(dnBar[i]) {LowBarPrice=L[i];}// DOWN BAR IN SHORT SWING SHOULD GIVE NEW LOW
if(dnBar[i] AND NOT upBar[i]){ upCount=0;}
}
}
// Swing chart drawn here
_SECTION_END();
Your LowBarPrice doesn't have an array indexer on it. Also, you initialize it as null and it stays that way because you never assign any value to it after initialization. So technically, in your condition, you're saying, if L[i] < null.
Write your conditions outside the loop. That'll create an array that will hold your price until you reference it in the loop.
So, for example, initialize LowBarPrice like this:
LowBarPrice = ValueWhen(DownBar, Ref(L,-1));
Thereafter, you'll get the price when you reference it in the loop.
if(L[i] < LowBarPrice[i])
This article really helped me get my head around looping in AmiBroker. It might give some context around your issue. The part that relates specifically to your question is under the section "Array Indexing
http://www.amibrokerforum.com/index.php?topic=50.0

Omnet++ : changing the location of function didn't work as expected

I am actually trying to edit the etherhost2 function to send to several destinations and I reached a point where it is possible only for the first time.
In the original code the function is working properly by just moving the two functions sendBurstPackets() and scheduleNextPacket(simTime()) in if condition with destMACAddress = resolveDestMACAddress() those two functions are only called once.
Does that mean that destMacAddress is set once through the whole simulation?
Original Code
void EtherTrafGen::handleMessage(cMessage *msg)
{
if (!isNodeUp())
throw cRuntimeError("Application is not running");
if (msg->isSelfMessage()) {
if (msg->getKind() == START) {
destMACAddress = resolveDestMACAddress();
// if no dest address given, nothing to do
if (destMACAddress.isUnspecified())
return;
}
sendBurstPackets();
scheduleNextPacket(simTime());
}
else
receivePacket(check_and_cast<cPacket *>(msg));
}
My Changes
void EtherTrafGen::handleMessage(cMessage *msg)
{
if (!isNodeUp())
throw cRuntimeError("Application is not running");
if (msg->isSelfMessage()) {
if (msg->getKind() == START) {
if (!multipacket)
{
destMACAddress = resolveDestMACAddress();
sendBurstPackets();
scheduleNextPacket(simTime());
}
// if no dest address given, nothing to do
if (destMACAddress.isUnspecified())
return;
}
}
else
receivePacket(check_and_cast<cPacket *>(msg));
}
The first message is only true for that condition (msg->getKind() == START), which means the the mac is set once for each host through the whole simulation. Removing that condition made it work.
I am worried if there are other self messages that might be mistaken with that function. Would be better to have separate EtherHost app that only works for my simulation.
If there is an idea how to look at all self messages, I would appreciate if some one informed me.

If Rectangle doesn't Contains Mouse Position

I have a Rectangle which I can touch with this command below.
if ((mouse.LeftButton == ButtonState.Pressed )&&
TextureRectangle.Contains((int)MousePos.X,(int)MousePos.Y))
{
// Action;
}
But is there a Command like "Not Contains", so I wanna do something else if the user touch out of the "TextureRectangle" area?
When I click to the Rectangle that both actions starts. I really dont know where the problem is.
if (mouse.LeftButton == ButtonState.Pressed){
if(TextureRectangle.Contains((int)MousePos.X, (int)MousePos.Y)) {
music1.Play();
}
else{
music2.Play();
}
}
my problem is that music1 and music2 plays at same time if i click on the Rectangle, i want that when i click on the Rectangle that music1 plays only (here is the problem , both starts to play)and when i click out of the Rectangle should start only music2 to play ( this case is ok)
I would strongly recommend you to get a programming book / ebook and start reading it. This is basic computer logic stuff.
if (mouse.LeftButton == ButtonState.Pressed)
{
if (TextureRectangle.Contains((int)MousePos.X, (int)MousePos.Y))
{
// inside
}
else
{
// outside
}
}
OR
if (mouse.LeftButton == ButtonState.Pressed)
{
if (!TextureRectangle.Contains((int)MousePos.X, (int)MousePos.Y))
{
// outside
}
else
{
// inside
}
}

Resources