Does GPIO.IN need to be linked to GPIO.OUT in RPi.GPIO in order for it to work properly? - raspberry-pi

I was writing code on an raspbian emulator with GPIO. I am able to get it to work, but for some reason when I change the order of GPIO.HIGH and the print statement in the conditionals, it does not run properly and stops after the first click. Anyone know if this is an issue with the emulator or just a property of raspberry pi and hooking it up to hardware? It also does not work at all if I do not link the GPIO.IN with a GPIO.OUT.
this gif shows what happens when I change order or remove - It turns on the first time, but it does not turn off or on again after that. It for some reason breaks it out of the while loop.
Here is the code I am using:
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BOARD)
import time
#initialise a previous input variable to 0 (assume button not pressed last)
prev_input = 0
prev_input1 = 0
inputs = [11, 13, 15]
outputs = [3, 5, 7]
GPIO.setup(inputs, GPIO.IN)
GPIO.setup(outputs, GPIO.OUT)
secs = 0
def main():
while True:
button_press(15, 7)
timer = add_secs(11, 5, 2)
#print(timer)
def button_press(button1, button2):
#take a reading
global prev_input
inputa = GPIO.input(button1)
#if the last reading was low and this one high, print
if ((not prev_input) and inputa):
print("Light on")
GPIO.output(button2, GPIO.HIGH) #code does not work if I remove/reorder this statement
if((not inputa) and prev_input):
print("Light off")
GPIO.output(button2, GPIO.LOW) #code does not work if I remove/reorder this statement
#update previous input
prev_input = inputa
#slight pause to debounce
time.sleep(0.05)
def add_secs(button1, button2, num):
global prev_input1
secs = 0
inputa = GPIO.input(button1)
if((not prev_input1) and inputa):
secs = num
print(secs)
GPIO.output(button2, GPIO.LOW) #code does not work if I remove/reorder this statement
prev_input1 = inputa
time.sleep(0.05)
return secs
main()

I contacted the developer of the emulator and he let me know there was an issue with the emulator that is now resolved.
The code runs properly after clearing the browsing data in chrome and re-running the program.

Related

Unreset GPIO Pins While System Resetting

Is it possible to unreset some GPIO pins while using NVIC_SystemReset function at STM32 ?
Thanks in advance for your answers
Best Regards
I try to reach NVIC_SystemReset function. But not clear inside of this function.
Also this project is running on KEIL
Looks like it is not possible, NVIC_SystemReset issues a general reset of all subsystems.
But probably, instead of system reset, you can just reset all peripheral expect one you need keep working, using peripheral reset registers in Reset and Clock Control module (RCC): RCC_AHB1RSTR, RCC_AHB2RSTR, RCC_APB1RSTR, RCC_APB1RSTR.
Example:
// Issue reset of SPI2, SPI3, I2C1, I2C2, I2C3 on APB1 bus
RCC->APB1RSTR = RCC_APB1RSTR_I2C3RST | RCC_APB1RSTR_I2C2RST | RCC_APB1RSTR_I2C1RST
| RCC_APB1RSTR_SPI3RST | RCC_APB1RSTR_SPI2RST;
__DMB(); // Data memory barrier
RCC->APB1RSTR = 0; // deassert all reset signals
See detailed information in RCC registers description in Reference Manual for your MCU.
You may also need to disable all interrupts in NVIC:
for (int i = 0 ; i < 8 ; i++) NVIC->ICER[i] = 0xFFFFFFFFUL; // disable all interrupts
for (int i = 0 ; i < 8 ; i++) NVIC->ICPR[i] = 0xFFFFFFFFUL; // clear all pending flags
if you want to restart the program, you can reload stack pointer to its top value, located at offset 0 of the flash memory and jump to the start address which is stored at offset 4. Note: flash memory is addressed starting from 0x08000000 address in the address space.
uint32_t stack_top = *((volatile uint32_t*)FLASH_BASE);
uint32_t entry_point = *((volatile uint32_t*)(FLASH_BASE + 4));
__set_MSP(stack_top); // set stack top
__ASM volatile ("BX %0" : : "r" (entry_point | 1) ); // jump to the entry point with bit 1 set

How to change quantum in xv6? [duplicate]

Right now it seems that on every click tick, the running process is preempted and forced to yield the processor, I have thoroughly investigated the code-base and the only relevant part of the code to process preemption is below (in trap.c):
// Force process to give up CPU on clock tick.
// If interrupts were on while locks held, would need to check nlock.
if(myproc() && myproc() -> state == RUNNING && tf -> trapno == T_IRQ0 + IRQ_TIMER)
yield();
I guess that timing is specified in T_IRQ0 + IRQ_TIMER, but I can't figure out how these two can be modified, these two are specified in trap.h:
#define T_IRQ0 32 // IRQ 0 corresponds to int T_IRQ
#define IRQ_TIMER 0
I wonder how I can change the default RR scheduling time-slice (which is right now 1 clock tick, fir example make it 10 clock-tick)?
If you want a process to be executed more time than the others, you can allow it more timeslices, *without` changing the timeslice duration.
To do so, you can add some extra_slice and current_slice in struct proc and modify the TIMER trap handler this way:
if(myproc() && myproc()->state == RUNNING &&
tf->trapno == T_IRQ0+IRQ_TIMER)
{
int current = myproc()->current_slice;
if ( current )
myproc()->current_slice = current - 1;
else
yield();
}
Then you just have to create a syscall to set extra_slice and modify the scheduler function to reset current_slice to extra_slice at process wakeup:
// Switch to chosen process. It is the process's job
// to release ptable.lock and then reacquire it
// before jumping back to us.
c->proc = p;
switchuvm(p);
p->state = RUNNING;
p->current_slice = p->extra_slice
You can read lapic.c file:
lapicinit(void)
{
....
// The timer repeatedly counts down at bus frequency
// from lapic[TICR] and then issues an interrupt.
// If xv6 cared more about precise timekeeping,
// TICR would be calibrated using an external time source.
lapicw(TDCR, X1);
lapicw(TIMER, PERIODIC | (T_IRQ0 + IRQ_TIMER));
lapicw(TICR, 10000000);
So, if you want the timer interrupt to be more spaced, change the TICR value:
lapicw(TICR, 10000000); //10 000 000
can become
lapicw(TICR, 100000000); //100 000 000
Warning, TICR references a 32bits unsigned counter, do not go over 4 294 967 295 (0xFFFFFFFF)

How to modify process preemption policies (like RR time-slices) in XV6?

Right now it seems that on every click tick, the running process is preempted and forced to yield the processor, I have thoroughly investigated the code-base and the only relevant part of the code to process preemption is below (in trap.c):
// Force process to give up CPU on clock tick.
// If interrupts were on while locks held, would need to check nlock.
if(myproc() && myproc() -> state == RUNNING && tf -> trapno == T_IRQ0 + IRQ_TIMER)
yield();
I guess that timing is specified in T_IRQ0 + IRQ_TIMER, but I can't figure out how these two can be modified, these two are specified in trap.h:
#define T_IRQ0 32 // IRQ 0 corresponds to int T_IRQ
#define IRQ_TIMER 0
I wonder how I can change the default RR scheduling time-slice (which is right now 1 clock tick, fir example make it 10 clock-tick)?
If you want a process to be executed more time than the others, you can allow it more timeslices, *without` changing the timeslice duration.
To do so, you can add some extra_slice and current_slice in struct proc and modify the TIMER trap handler this way:
if(myproc() && myproc()->state == RUNNING &&
tf->trapno == T_IRQ0+IRQ_TIMER)
{
int current = myproc()->current_slice;
if ( current )
myproc()->current_slice = current - 1;
else
yield();
}
Then you just have to create a syscall to set extra_slice and modify the scheduler function to reset current_slice to extra_slice at process wakeup:
// Switch to chosen process. It is the process's job
// to release ptable.lock and then reacquire it
// before jumping back to us.
c->proc = p;
switchuvm(p);
p->state = RUNNING;
p->current_slice = p->extra_slice
You can read lapic.c file:
lapicinit(void)
{
....
// The timer repeatedly counts down at bus frequency
// from lapic[TICR] and then issues an interrupt.
// If xv6 cared more about precise timekeeping,
// TICR would be calibrated using an external time source.
lapicw(TDCR, X1);
lapicw(TIMER, PERIODIC | (T_IRQ0 + IRQ_TIMER));
lapicw(TICR, 10000000);
So, if you want the timer interrupt to be more spaced, change the TICR value:
lapicw(TICR, 10000000); //10 000 000
can become
lapicw(TICR, 100000000); //100 000 000
Warning, TICR references a 32bits unsigned counter, do not go over 4 294 967 295 (0xFFFFFFFF)

I am trying to create cookie clicker in python. I have implemented an autoclicker, however, each time I click it adds another autoclicker

I am fairly new to python and I have challenged myself to create a cookie clicker like game using python and Tkinter. I have just implemented an autoclicker but I am having an issue where each time I click, another autoclicker is added.
I want it so that the user can continue to click, but when the auto clicker is activated, it will automatically add 1 click per second.
I have tried puting window.after(1000, nClick) on different lines as well as adjusting the value. I have tried making new functions but I just can't seem to get it working.
import sys
import random
import tkinter
import time
global counter
counter = 0
autoclicker = counter + 1
def nClick():
global counter
global autoclicker
counter += 1
mButton1.config(text = counter)
print(counter)
if counter >= 10:
autoclicker
window.after(1000, nClick)
window = tkinter.Tk()
# to rename the title of the window
window.title("GUI")
# pack is used to show the object in the window
mButton1 = tkinter.Button(text = counter, command = nClick, fg = "darkgreen", bg = "white")
mButton1.pack()
mButton1.config(font=("Courier", 44))
window.mainloop()
#input('Press ENTER to exit')
I expect the counter to automatically + 1 to counter after 10 clicks. It does this until the user clicks again where it automatically adds the click to the autoclicker
You need to separate out the things "user clicks to add a cookie", "autoclicker adds a cookie", and "turn autoclicker on/off", so there are clear places where those things happen. e.g.
import sys
import random
import tkinter
import time
global counter
counter = 0
autoclicker_enabled = False
# autoclicker gets its own function to call,
# which updates the counter,
# and calls itself
def autoClick():
global counter
counter += 1
mButton1.config(text = counter)
window.after(1000, autoClick)
def nClick():
global counter
global autoclicker_enabled
counter += 1
mButton1.config(text = counter)
print(counter)
if counter >= 10:
# autoclicker_enabled is a toggle,
# so autoclicker can only be enabled once.
# It starts the autoClick self-loop,
# and then sets itself so that won't happen again.
if not autoclicker_enabled:
window.after(1000, autoClick)
autoclicker_enabled = True
window = tkinter.Tk()
# to rename the title of the window
window.title("GUI")
# pack is used to show the object in the window
mButton1 = tkinter.Button(text = counter, command = nClick, fg = "darkgreen", bg = "white")
mButton1.pack()
mButton1.config(font=("Courier", 44))
window.mainloop()
You can then see that the autoClick function does not print the text as well, and that the counter increase and button text change code is repeated, and maybe move that out to its own function, which both clicks use..

Storage values using os.stat(filename)

I'm trying to create an EDUCATIONAL PURPOSES ONLY virus. I do not plan on spreading it. It's purpose is to grow a file to the point your storage is full and slow your computer down. It prints the size of the file every 0.001 seconds. With that, I also want to know how fast it is growing the file. The following code doesn't seem to let it run:
class Vstatus():
def _init_(Status):
Status.countspeed == True
Status.active == True
Status.growingspeed == 0
import time
import os
#Your storage is at risk of over-expansion. Please do not let this file run forever, as your storage will fill continuously.
#This is for educational purposes only.
while Vstatus.Status.countspeed == True:
f = open('file.txt', 'a')
f.write('W')
fsize = os.stat('file.txt')
Key1 = fsize
time.sleep(1)
Key2 = fsize
Vstatus.Status.growingspeed = (Key2 - Key1)
Vstatus.Status.countspeed = False
while Vstatus.Status.active == True:
time.sleep(0.001)
f = open('file.txt', 'a')
f.write('W')
fsize = os.stat('file.txt')
print('size:' + fsize.st_size.__str__() + ' at a speed of ' + Vstatus.Status.growingspeed + 'bytes per second.')
This is for Educational Purposes ONLY
The main error I keep getting when running the file is here:
TypeError: unsupported operand type(s) for -: 'os.stat_result' and 'os.stat_result'
What does this mean? I thought os.stat returned an integer Can I get a fix on this?
Vstatus.Status.growingspeed = (Key2 - Key1)
You can't subtract os.stat objects. Your code also has some other problems. Your loops will run sequentially, meaning that your first loop will try to estimate how quickly the file is being written to without writing anything to the file.
import time # Imports at the top
import os
class VStatus:
def __init__(self): # double underscores around __init__
self.countspeed = True # Assignment, not equality test
self.active = True
self.growingspeed = 0
status = VStatus() # Make a VStatus instance
# You need to do the speed estimation and file appending in the same loop
with open('file.txt', 'a+') as f: # Only open the file once
start = time.time() # Get the current time
starting_size = os.fstat(f.fileno()).st_size
while status.active: # Access the attribute of the VStatus instance
size = os.fstat(f.fileno()).st_size # Send file desciptor to stat
f.write('W') # Writing more than one character at a time will be your biggest speed up
f.flush() # make sure the byte is written
if status.countspeed:
diff = time.time() - start
if diff >= 1: # More than a second has gone by
status.countspeed = False
status.growingspeed = (os.fstat(f.fileno()).st_size - starting_size)/diff # get rate of growth
else:
print(f"size: {size} at a speed of {status.growingspeed}")