Im busy working on a dimming light which my ESP-03 will control. But what I have read up on, I have a problem. Please see my code below then I will explain:
device_id = "553CDA2DEAC90"
query_id = ""
dim = 120
wifi.setmode(wifi.STATION)
wifi.sta.config("SSID","PASSWORD")
wifi.sta.connect()
wifi.sta.setip({ip="10.0.0.122",netmask="255.255.255.0",gateway="10.0.0.2"})
outpin = 7 --GPIO13
gpio.mode(outpin,gpio.OUTPUT)
gpio.write(outpin,gpio.LOW)
inpin = 6 --GPIO12
gpio.mode(inpin,gpio.INT,gpio.PULLUP)
function zero_cross()
dt = 75*dim
tmr.delay(dt)
gpio.write(outpin,gpio.HIGH)
tmr.delay(1)
gpio.write(outpin,gpio.LOW)
tmr.wdclr()
end
gpio.trig(inpin,"up",zero_cross)
function sendData()
if(wifi.sta.status() == 5)then
conn=net.createConnection(net.TCP, 0)
conn:connect(PORT,'IP')
if(firstStart == 0)then
conn:send(device_id)
conn:send("|0|")
else
if(query_id == nil)then
conn:send(device_id)
conn:send("|0|")
conn:send(dim)
else
conn:send(device_id)
conn:send("|")
conn:send(query_id)
conn:send("|")
conn:send(dim)
query_id = nil
end
end
conn:on("receive", function(conn, payload)
payload = string.gsub(payload, " ", "")
dim = string.sub(payload, 0, string.find(payload, "|")-1)
payload = string.gsub(payload, dim.."|", "")
query_id = payload
conn:close()
end)
else
wifi.sta.connect()
end
end
tmr.alarm(6, 1000, 1, sendData )
The problem that I am facing is that when at the bottom of the script I start tmr.alarm()... But the under the function zero_cross() its uses tmr.delay and that seems to make tmr.alarm() not function anymore. All that happens is the ESP just keeps on restarting. If I run the above code seperate (just the dimming function or just the sendData function then everything works perfect). Does anyone have any suggestions?
Nodemcu call lua callback directly from hardware interrupt, while the need to use luahook, (As Lua doesn’t have direct support for interrupts, they have to be emulated). It is probably dangerous.
Solution: use only 1 interrupt same time:
local send_time, last_gpio
last_gpio = gpio.read(6)
send_time = 0
tmr.trigger(1, 10, 1, function()
if (gpio.read(6) == 1 and last_gpio == 0) then
last_gpio = 1
zero_cross()
else if (gpio.read(6) == 0 and last_gpio == 1)
last_gpio = 0
end
send_time = send_time + 1
if (send_time > 100) then
send_data()
end
end)
Related
I was making custom chat system and I faced this "bug".
just textbox returns "", not nil.
and there is no any error. even without
string.len(script.Parent.Parent.message.Text) > 0
"if" part.
local db = false
local TextService = game:GetService("TextService")
script.Parent.MouseButton1Click:Connect(function ()
local plr = script.Parent.Parent.Parent.Parent.Parent.Parent
local dn = plr.Character.Humanoid.DisplayName
local muted = script.Parent.muted.Value
local mod = script.Parent.moderator.Value
if db == false and muted == false and string.len(script.Parent.Parent.message.Text) > 0 then
db = true
local ts = 16
local msg = script.Parent.Parent.chat.message0:Clone()
--problem line
msg.messageContent.Text = TextService:FilterStringAsync(script.Parent.Parent.message.Text, plr.UserId, "2")
if string.len(script.Parent.Parent.message.Text) > 130 then
ts = 14
end
msg.messageContent.TextSize = ts
--problem ends
local ps = msg.prefixes
ps.bot.Visible = false
local counter = game.ReplicatedStorage.ChatBlockStorage.counter.Value
msg.Name = "message" .. counter
msg.actualName.Text = "#" .. plr.Name
msg.displayName.Text = dn
msg.icon.Image = game.Players:GetUserThumbnailAsync(plr.UserId, Enum.ThumbnailType.HeadShot, Enum.ThumbnailSize.Size420x420)
msg.icon.ResampleMode = "Default"
if script.Parent.Parent.message.customIcon.locked.Visible == false then
msg.icon.Image = "http://www.roblox.com/asset/?id=" .. script.Parent.Parent.message.customIcon.Text
end
if msg.Name == "message1" then
mod = true
end
if mod == true then
ps.mod.Visible = true
end
counter += 1
script.Parent.Parent.message.Text = ""
wait(game.ReplicatedStorage.ChatBlockStorage.waitTime.Value)
db = false
end
end)
any ideas how to fix it?
Use the FocustLost event. Here is the roblox documentation on it.
Example:
script.Parent.FocusLost:Connect(function(enterPressed)
if enterPressed then
print("Focus was lost because enter was pressed!")
end
end)
Near the end of the code, you write
script.Parent.Parent.message.Text = ""
Would this not be the cause?
maybe you can do tostring(msg)?
this prob wont work
tostring("i like beans")
read more on strings here:https://developer.roblox.com/en-us/articles/String
read more on tostring() here: https://devforum.roblox.com/t/what-does-assert-and-tostring-do/1047653
(none are people i know but i looked through them and they have valid info)
good luck my brother
So here's the deal, I'm working on a game that is similar to a murder mystery and this part of the system is to start the round and show the players their roles and then the map. Except it used to work and I didn't knowingly do anything to the scripts that would affect it so the game crashes when this part is carried out. All I know is it starts to display the role and often does, it also plays the sound and displays the correct description, however it crashes just after that and sometimes just before the role is revealed. I've attached the function that runs when the RoundStarter event is fired to the client.
The server doesn't crash but, all of the clients do but not all at the exact same moment in time; Previously when there has been errors, I've been able to identify an error message but none of the clients throw any clear issues.
In testing mode in Roblox Studio, they freeze just after the drum roll sound effect as the role is displayed, however no errors and the server seems to be acting normally. Near enough the same thing happens when ran in Roblox.
Clientside script
ReplicatedStorage.Players.Events.RoundStarter.OnClientEvent:Connect(function(Role,Map)
local player = game.Players.LocalPlayer
player.CameraMode = Enum.CameraMode.LockFirstPerson
script.Parent.RoundGui.RoundEnd.Visible = false
game.Players.LocalPlayer.NameDisplayDistance = 0
CURRENTROLE = Role
CURRENTMAP = Map
script.Parent.RoundGui.Enabled = true
script.Parent.RoundGui.RoundStarter.Visible = true
script.Parent.RoundGui.RoundStarter.Fader.Visible = true
script.Parent.RoundGui.RoundStarter.Fader.BackgroundTransparency = 0
script.Parent.RoundGui.RoundStarter.RoleDescription.Visible = false
script.Parent.RoundGui.RoundStarter.RoleName.Visible = false
script.Parent.RoundGui.RoundStarter.Text.Visible = true
local transp = 0
for i = 1,50,1 do
transp += 0.05
script.Parent.RoundGui.RoundStarter.Fader.BackgroundTransparency = transp
wait(.1)
end
script.Parent.RoundGui.RoundStarter.DR:Play()
script.Parent.RoundGui.RoundStarter.RoleName.Visible = true
script.Parent.RoundGui.RoundStarter.RoleName.Text = Role
script.Parent.RoundGui.RoundStarter.RoleDescription.Visible = true
if Role == "Civilian" then
script.Parent.RoundGui.RoundStarter.RoleDescription.Text = "Your Job is to help the Inspector find the shadow... Work to figure them out and stop them before it's too late! Don't tell anyone your Role!"
script.Parent.RoundGui.RoundStarter.RoleName.TextColor3 = Color3.fromRGB(0, 255, 17)
elseif Role == "Shadow" then
script.Parent.RoundGui.RoundStarter.RoleName.TextColor3 = Color3.fromRGB(255, 0, 0)
script.Parent.RoundGui.RoundStarter.RoleDescription.Text = "It's time... Infiltrate the crowd, gain their trust and kill the inspector to win! By killing another player, You can take on their form and blend in with the Civilians. More help will be on left of the screen. Don't tell anyone your Role!"
elseif Role == "Inspector" then
script.Parent.RoundGui.RoundStarter.RoleName.TextColor3 = Color3.fromRGB(0, 38, 255)
script.Parent.RoundGui.RoundStarter.RoleDescription.Text = "You are nominated to fight the Shadow and eliminate them. You must work with the Civilians to figure out who the Shadow is, if you die you lose. Don't tell anyone your Role!"
end
wait(10)
script.Parent.RoundGui.RoundStarterMap.Visible = true
script.Parent.RoundGui.RoundStarterMap.Fader.Visible = true
script.Parent.RoundGui.RoundStarterMap.MapDescription.Visible = false
script.Parent.RoundGui.RoundStarterMap.MapName.Visible = false
local transp = 0
for i = 1,50,1 do
transp += 0.05
script.Parent.RoundGui.RoundStarterMap.Fader.BackgroundTransparency = transp
wait(.1)
end
script.Parent.RoundGui.RoundStarterMap.MapName.Visible = true
script.Parent.RoundGui.RoundStarterMap.MapName.Text = Map
script.Parent.RoundGui.RoundStarter.Dun:Play()
if Map == "The Office" then
script.Parent.RoundGui.RoundStarterMap.MapDescription.Text = "A classic map based in an Office building, in a power cut, near midnight. With an outdoor and Indoor area to explore, will you survive?"
elseif Map =="The Village" then
script.Parent.RoundGui.RoundStarterMap.MapDescription.Text = "The original map based in a small villiage with numerous buildings and areas to explore."
end
script.Parent.RoundGui.RoundStarterMap.MapDescription.Visible = true
wait(10)
script.Parent.RoundGui.RoundEnd.Visible = false
script.Parent.RoundGui.RoundStarterMap.Visible = false
script.Parent.RoundGui.RoundStarter.Visible = false
end)
--This is the next function in the code that should be executed at a similar time to the above one (It should have an InMap value of true.
ReplicatedStorage.Players:WaitForChild(player.Name).InMap.Changed:Connect(function()
data = game.ReplicatedStorage.GetPlayerDataCS:InvokeServer()
if ReplicatedStorage.Players[player.Name].InMap.Value == false then
--StartGUI:SetCoreGuiEnabled(Enum.CoreGuiType.PlayerList, true)
player.CameraMode = Enum.CameraMode.Classic
--StartGUI:SetCoreGuiEnabled(Enum.CoreGuiType.Chat,true)
script.Parent.LobbyGui.Enabled = true
script.Parent.RoundGui.Enabled = false
wait()
else
if CURRENTROLE == "Shadow" then
script.Parent.RoundGui.ShadowPanel.Visible = true
script.Parent.RoundGui.CivPanel.Visible = false
script.Parent.RoundGui.InsPanel.Visible = false
if data then
if data.EquippedAbility ~="None" and data.EquippedAbility ~="" then
script.Parent.RoundGui.ShadowPanel[data.EquippedAbility].Visible = true
end
end
elseif CURRENTROLE == "Inspector" then
script.Parent.RoundGui.ShadowPanel.Visible = false
script.Parent.RoundGui.CivPanel.Visible = false
script.Parent.RoundGui.InsPanel.Visible = true
else
script.Parent.RoundGui.ShadowPanel.Visible = false
script.Parent.RoundGui.CivPanel.Visible = true
script.Parent.RoundGui.InsPanel.Visible = false
end
--StartGUI:SetCoreGuiEnabled(Enum.CoreGuiType.PlayerList, false)
--StartGUI:SetCoreGuiEnabled(Enum.CoreGuiType.Chat,true)
script.Parent.LobbyGui.Enabled = false
script.Parent.RoundGui.Enabled = true
wait()
end
end)
Here's also the script on the server that should be near the event.
local replicatedstor = game:GetService("ReplicatedStorage")
local playersinthemap = {}
local playersinserver = game.Players:GetPlayers()
local maplist = {"The Village"}
local TESTINGMODE = false
local goodwin = false
local COUNT = 0
local deadpool = {}
local DataStoreService = game:GetService("DataStoreService")
local Datastore = DataStoreService:GetDataStore("THE_MASQUERADE_TEST2")
function UpdateStatuses(Playerr,NewStatus)
local c = Playerr
if NewStatus == "Lobby" or NewStatus == "AFK" then
if game.ReplicatedStorage.Players[c.Name].Status.Value == "Shadow" then
script.RoundsInProgress.Value = false
goodwin = true
elseif game.ReplicatedStorage.Players[c.Name].Status.Value == "Inspector" then
script.RoundsInProgress.Value = false
goodwin = false
end
game.ReplicatedStorage.Players[c.Name].InMap.Value = false
if table.find(playersinthemap,c,1)~= nil then
local index = table.find(playersinthemap,c,1)
table.remove(playersinthemap,index)
end
end
game.ReplicatedStorage.Players[c.Name].Status.Value = NewStatus
if #playersinthemap <= 2 and script.RoundsInProgress.Value == true then
script.RoundsInProgress.Value = false
goodwin = false
end
end
game.ReplicatedStorage.Players.Events.SetStatus.OnServerEvent:Connect(function(Player,Status)
if Status ~= nil then
UpdateStatuses(Player,Status)
else
print ("Tried to change status of Player but the given status was nil.")
end
end)
while true do
while script.RoundsRunning.Value == true do
game.ReplicatedStorage.Players.Events.Notify:FireAllClients("Intermission...","L",false)
--game.ReplicatedStorage.Game.Intermission:Fire(30)
--game.ReplicatedStorage.Game.Intermission.Event:Wait()
wait(35)
game.Workspace.Lobby.DATABOARD.SurfaceGui.Frame.Title.Text = "Round starting soon..."
--game.ReplicatedStorage.Players.Events.Notify:FireAllClients("Round starting soon...","L",true)
--game.Workspace.Lobby.DATABOARD.SurfaceGui.Frame.Time.Text = ""
if not game.Workspace.Map then
playersinthemap = {}
local Mapfolder = Instance.new("Folder",game.Workspace)
Mapfolder.Name = "Map"
end
playersinserver = game.Players:GetPlayers()
wait(10)
playersinserver = game.Players:GetPlayers()
if #playersinserver >= 4 or (TESTINGMODE == true and #playersinserver >= 3) then
game.Workspace.Lobby.DATABOARD.SurfaceGui.Frame.Title.Text = "Round loading..."
game.ReplicatedStorage.Players.Events.Notify:FireAllClients("Loading the round now...","L",false)
playersinserver = game.Players:GetPlayers()
local chosenMapIndex = math.random(#maplist)
local chosenMapName = maplist[chosenMapIndex]
local chosenShadowIndex = math.random(#playersinserver)
local chosenShadow = playersinserver[chosenShadowIndex]
local chosenInspectorIndex = math.random(#playersinserver)
local chosenInspector = playersinserver[chosenInspectorIndex]
while chosenInspector == chosenShadow do
chosenInspectorIndex = math.random(#playersinserver)
chosenInspector = playersinserver[chosenInspectorIndex]
end
local playernumber = playersinserver
COUNT = 0
while COUNT ~= #playersinserver do
COUNT += 1
local playername = playersinserver[COUNT].Name
print (playersinserver)
print ("Player trying to send role data:"..playername)
if playersinserver[COUNT] == chosenShadow then
game.ReplicatedStorage.Players.Events.RoundStarter:FireClient(playersinserver[COUNT],"Shadow",chosenMapName)
game.ReplicatedStorage.Players[playersinserver[COUNT].Name].Status.Value = "Shadow"
--temp = game.ReplicatedStorage.ReadStatus:Invoke(playername,"Shadow")
elseif playersinserver[COUNT] == chosenInspector then
game.ReplicatedStorage.Players.Events.RoundStarter:FireClient(playersinserver[COUNT],"Inspector",chosenMapName)
game.ReplicatedStorage.Players[playersinserver[COUNT].Name].Status.Value = "Inspector"
--temp = game.ReplicatedStorage.ReadStatus:Invoke(playername,"Inspector")
else
game.ReplicatedStorage.Players.Events.RoundStarter:FireClient(playersinserver[COUNT],"Civilian",chosenMapName)
game.ReplicatedStorage.Players[playersinserver[COUNT].Name].Status.Value = "Civilian"
--temp = game.ReplicatedStorage.ReadStatus:Invoke(playername,"Civilian")
end
end
wait()
local MapInServerStorage = game.ServerStorage.Maps:FindFirstChild(chosenMapName)
local LoadedMap = MapInServerStorage:Clone()
LoadedMap.Parent = game.Workspace.Map
local spawns = {}
for i,c in pairs(LoadedMap:GetDescendants()) do
if c.Name == "Spawn" then
table.insert(spawns,1,c)
end
end
COUNT = 0
local i = COUNT
while COUNT ~= #playersinserver do
COUNT += 1
print ("Setting Character locations. Loop:"..COUNT)
local spawnlistindex = math.random(#spawns)
playersinserver[COUNT].Character:SetPrimaryPartCFrame(spawns[spawnlistindex].CFrame)
--playersinserver[COUNT].Character:SetPrimaryPartCFrame(LoadedMap.Spawns.Spawn.CFrame)
table.insert(playersinthemap,1,playersinserver[COUNT])
playersinserver[COUNT].NameDisplayDistance = 0
game.ReplicatedStorage.Players:FindFirstChild(playersinserver[COUNT].Name).InMap.Value = true
if playersinserver[COUNT] == chosenInspector then
local data = game.ReplicatedStorage.GetPlayerData:Invoke(chosenInspector)
Pistl = game.ServerStorage.Guns[data.EquippedSkin]:Clone()
Pistl.Parent = playersinserver[COUNT].Backpack
end
end
print ("Round starting...")
--This is then followed by the rest of the round system which should be working but I have cut it to try to shorten the amount of reading but can be supplied if needed. It is closed correctly.
I've tried to keep the code to a minimum however it could be anywhere and as there are no obvious script related error codes, I'm requesting some assistance in some way.
There are other things that may have caused it but this is becoming a real issue, especially since it used to work, and I've included all of the likely suspects but I'm happy to give anything else if these aren't incorrect in anyway.
If you wish to see what happens yourself, you'll need either 4 Roblox Accounts or 3 extra friends.
Here's the game on Roblox: The Masquerade
If anything else is needed, feel free to let me know and thanks for reading and any potential help. (Just so you know, I have done a lot of research on all of the functions and things I'm using but I can't find any issues, it just freezes & crashes).
The only error codes I've got are:
Start Process Exception...
Uploading crash analytics
Done uploading crash analytics
There are some random wait() statements without any arguments, which shouldn't be in your code anyway. This may very well hang up the server / client.
Also, you appear to have a few while loops which do not have any wait()'s. That's a pretty common problem which stalls the client executing the script. Try adding at least
wait(0.01) to the end of each while true loop that doesn't have it already.
There might be some occurences of this in the client as well (like that one lonely wait() with no parameters), but here's a modified version of your server script:
while true do
while script.RoundsRunning.Value == true do
game.ReplicatedStorage.Players.Events.Notify:FireAllClients("Intermission...","L",false)
--game.ReplicatedStorage.Game.Intermission:Fire(30)
--game.ReplicatedStorage.Game.Intermission.Event:Wait()
wait(35)
game.Workspace.Lobby.DATABOARD.SurfaceGui.Frame.Title.Text = "Round starting soon..."
--game.ReplicatedStorage.Players.Events.Notify:FireAllClients("Round starting soon...","L",true)
--game.Workspace.Lobby.DATABOARD.SurfaceGui.Frame.Time.Text = ""
if not game.Workspace.Map then
playersinthemap = {}
local Mapfolder = Instance.new("Folder",game.Workspace)
Mapfolder.Name = "Map"
end
playersinserver = game.Players:GetPlayers()
wait(10)
playersinserver = game.Players:GetPlayers()
if #playersinserver >= 4 or (TESTINGMODE == true and #playersinserver >= 3) then
game.Workspace.Lobby.DATABOARD.SurfaceGui.Frame.Title.Text = "Round loading..."
game.ReplicatedStorage.Players.Events.Notify:FireAllClients("Loading the round now...","L",false)
playersinserver = game.Players:GetPlayers()
local chosenMapIndex = math.random(#maplist)
local chosenMapName = maplist[chosenMapIndex]
local chosenShadowIndex = math.random(#playersinserver)
local chosenShadow = playersinserver[chosenShadowIndex]
local chosenInspectorIndex = math.random(#playersinserver)
local chosenInspector = playersinserver[chosenInspectorIndex]
while chosenInspector == chosenShadow do
chosenInspectorIndex = math.random(#playersinserver)
chosenInspector = playersinserver[chosenInspectorIndex]
end
local playernumber = playersinserver
COUNT = 0
while COUNT ~= #playersinserver do
COUNT += 1
local playername = playersinserver[COUNT].Name
print (playersinserver)
print ("Player trying to send role data:"..playername)
if playersinserver[COUNT] == chosenShadow then
game.ReplicatedStorage.Players.Events.RoundStarter:FireClient(playersinserver[COUNT],"Shadow",chosenMapName)
game.ReplicatedStorage.Players[playersinserver[COUNT].Name].Status.Value = "Shadow"
--temp = game.ReplicatedStorage.ReadStatus:Invoke(playername,"Shadow")
elseif playersinserver[COUNT] == chosenInspector then
game.ReplicatedStorage.Players.Events.RoundStarter:FireClient(playersinserver[COUNT],"Inspector",chosenMapName)
game.ReplicatedStorage.Players[playersinserver[COUNT].Name].Status.Value = "Inspector"
--temp = game.ReplicatedStorage.ReadStatus:Invoke(playername,"Inspector")
else
game.ReplicatedStorage.Players.Events.RoundStarter:FireClient(playersinserver[COUNT],"Civilian",chosenMapName)
game.ReplicatedStorage.Players[playersinserver[COUNT].Name].Status.Value = "Civilian"
--temp = game.ReplicatedStorage.ReadStatus:Invoke(playername,"Civilian")
end
end
-- wait() useless wait
local MapInServerStorage = game.ServerStorage.Maps:FindFirstChild(chosenMapName)
local LoadedMap = MapInServerStorage:Clone()
LoadedMap.Parent = game.Workspace.Map
local spawns = {}
for i,c in pairs(LoadedMap:GetDescendants()) do
if c.Name == "Spawn" then
table.insert(spawns,1,c)
end
end
COUNT = 0
local i = COUNT
while COUNT ~= #playersinserver do
COUNT += 1
print ("Setting Character locations. Loop:"..COUNT)
local spawnlistindex = math.random(#spawns)
playersinserver[COUNT].Character:SetPrimaryPartCFrame(spawns[spawnlistindex].CFrame)
--playersinserver[COUNT].Character:SetPrimaryPartCFrame(LoadedMap.Spawns.Spawn.CFrame)
table.insert(playersinthemap,1,playersinserver[COUNT])
playersinserver[COUNT].NameDisplayDistance = 0
game.ReplicatedStorage.Players:FindFirstChild(playersinserver[COUNT].Name).InMap.Value = true
if playersinserver[COUNT] == chosenInspector then
local data = game.ReplicatedStorage.GetPlayerData:Invoke(chosenInspector)
Pistl = game.ServerStorage.Guns[data.EquippedSkin]:Clone()
Pistl.Parent = playersinserver[COUNT].Backpack
end
wait(0.01)
end
wait(0.01)
end
These are just the rough steps, so implant the changes in your code the way you want them to be.
I tried to fix some Garry's Mod addon and this is what happens. I tried to fix it for long time, but I'm not the best in Lua coding :/ . What is wrong with this code? I get this error:
[ERROR] addons/garrys_bombs_5_base_528449144/lua/entities/gb5_shockwave_sound_lowsh.lua:80: bad argument #1 to 'SetPhysicsAttacker' (Entity expected, got nil)
1. SetPhysicsAttacker - [C]:-1
2. unknown - addons/garrys_bombs_5_base_528449144/lua/entities/gb5_shockwave_sound_lowsh.lua:80
And the code is pretty long. I have every file working fine, but this file is not working
AddCSLuaFile()
DEFINE_BASECLASS( "base_anim" )
if (SERVER) then
util.AddNetworkString( "gb5_net_sound_lowsh" )
end
ENT.Spawnable = false
ENT.AdminSpawnable = false
ENT.PrintName = ""
ENT.Author = ""
ENT.Contact = ""
ENT.GBOWNER = nil
ENT.MAX_RANGE = 0
ENT.SHOCKWAVE_INCREMENT = 0
ENT.DELAY = 0
ENT.SOUND = ""
net.Receive( "gb5_net_sound_lowsh", function( len, pl )
local sound = net.ReadString()
LocalPlayer():EmitSound(sound)
end );
function ENT:Initialize()
if (SERVER) then
self.FILTER = {}
self:SetModel("models/props_junk/watermelon01_chunk02c.mdl")
self:SetSolid( SOLID_NONE )
self:SetMoveType( MOVETYPE_NONE )
self:SetUseType( ONOFF_USE )
self.Bursts = 0
self.CURRENTRANGE = 0
self.GBOWNER = self:GetVar("GBOWNER")
self.SOUND = self:GetVar("SOUND")
end
end
function ENT:Think()
if (SERVER) then
if not self:IsValid() then return end
local pos = self:GetPos()
self.CURRENTRANGE = self.CURRENTRANGE+(self.SHOCKWAVE_INCREMENT*10)
if(GetConVar("gb5_realistic_sound"):GetInt() >= 1) then
for k, v in pairs(ents.FindInSphere(pos,self.CURRENTRANGE)) do
if v:IsPlayer() then
if not (table.HasValue(self.FILTER,v)) then
net.Start("gb5_net_sound_lowsh")
net.WriteString(self.SOUND)
net.Send(v)
v:SetNWString("sound", self.SOUND)
if self:GetVar("Shocktime") == nil then
self.shocktime = 1
else
self.shocktime = self:GetVar("Shocktime")
end
if GetConVar("gb5_sound_shake"):GetInt()== 1 then
util.ScreenShake( v:GetPos(), 5555, 555, self.shocktime, 500 )
end
table.insert(self.FILTER, v)
end
end
end
else
if self:GetVar("Shocktime") == nil then
self.shocktime = 1
else
self.shocktime = self:GetVar("Shocktime")
end
local ent = ents.Create("gb5_shockwave_sound_instant")
ent:SetPos( pos )
ent:Spawn()
ent:Activate()
ent:SetPhysicsAttacker(ply)
ent:SetVar("GBOWNER", self.GBOWNER)
ent:SetVar("MAX_RANGE",50000)
ent:SetVar("DELAY",0.01)
ent:SetVar("Shocktime",self.shocktime)
ent:SetVar("SOUND", self:GetVar("SOUND"))
self:Remove()
end
self.Bursts = self.Bursts + 1
if (self.CURRENTRANGE >= self.MAX_RANGE) then
self:Remove()
end
self:NextThink(CurTime() + (self.DELAY*10))
return true
end
end
function ENT:OnRemove()
if SERVER then
if self.FILTER==nil then return end
for k, v in pairs(self.FILTER) do
if not v:IsValid() then return end
v:SetNWBool("waiting", true)
end
end
end
function ENT:Draw()
return false
end
Is there a chance someone fix this for me? Or even just telling me what's wrong? I would be pleased. If needed I can send all files. Well... It's not my addon but I'm trying to fix an existing one. Someone tried to fix it too but he didn't (actually he broke it even more).
What the error means
Inside your ENT:Think() function, you are calling ent:SetPhysicsAttacker(ply)
ply is not defined anywhere inside that function, so is nil (Entity expected, got nil)
How to fix this
If no player is responsible for the damage caused by this entity, delete the line ent:SetPhysicsAttacker(ply).
Otherwise, assign an Owner to the entity at the point of creation, using SetOwner.
This would then allow you to use self:GetOwner() inside your Think hook
Example
hook.Add("PlayerSay", "SpawnEntity", function(ply, text)
if string.lower(text) == "!spawnentity" then
-- Create your entity
local myEntity = ents.Create("gb5_shockwave_sound_lowsh")
myEntity:SetPos(ply:GetPos())
myEntity:SetAngles(ply:GetAngles())
myEntity:Spawn()
-- Sets the owner to the player that typed the command
myEntity:SetOwner(ply)
return ""
end
end)
-- Inside your entity code
function ENT:Think()
print("My owner is: " .. tostring(self:GetOwner()))
-- ...
ent:SetPhysicsAttacker(self:GetOwner())
end
I have a motorized roller blind project.
I am following this instructable: https://www.instructables.com/id/Motorized-WiFi-IKEA-Roller-Blind/ .
I am using the code in the instructable, but I suspect tha fault is in one of these codes:
config.lua
-- file : config.lua
local module = {}
module.SSID = {}
module.SSID["ssid"] = "password"
-- example for local MQTT
--module.MQHOST = "ohab.local"
--module.MQPORT = 1883
--module.MQID = node.chipid()
--module.MQUSR = ""
--module.MQPW = ""
-- example for cloud MQTT
module.MQHOST = "192.***.*.*"
module.MQPORT = 1883
module.MQID = node.chipid()
module.MQUSR = "username"
module.MQPW = "password"
module.MQTLS = 1 -- 0 = unsecured, 1 = TLS/SSL
module.ENDPOINT = "/house/masterbedroom/rollerblind/"
module.ID = "0"
--module.SUB = "set"
module.SUB = {[module.ENDPOINT .. module.ID .. "/set"]=0,[module.ENDPOINT .. "all"]=0}
module.POST = module.ENDPOINT .. module.ID .. "/status"
return module
wifi_setup
-- file: setup.lua
local module = {}
local function wifi_wait_ip()
if wifi.sta.getip()== nil then
print("IP unavailable, Waiting...")
else
tmr.stop(1)
gpio.write(pin_led,1) --off
print("\n================== ==================")
print("ESP8266 mode is: " .. wifi.getmode())
print("MAC address is: " .. wifi.ap.getmac())
print("IP is "..wifi.sta.getip())
print("====================================")
mq.start()
end
end
local function wifi_start(list_aps)
if list_aps then
gpio.write(pin_led,0) --on
for key,value in pairs(list_aps) do
if config.SSID and config.SSID[key] then
wifi.setmode(wifi.STATION);
wifi.sta.config(key,config.SSID[key])
wifi.sta.connect()
print("Connecting to " .. key .. " ...")
--config.SSID = nil -- can save memory
tmr.alarm(1, 2500, 1, wifi_wait_ip)
end
end
else
print("Error getting AP list")
end
end
function module.start()
print("Configuring Wifi ...")
wifi.setmode(wifi.STATION);
wifi.sta.getap(wifi_start)
end
return module
Sadly I cant manage to go beyond step 4. After I have tried to download the code to the ESP8266 I only get this error:
PANIC: unprotected error in call to Lua API (wifi_setup.lua:25: bad argument #1 to 'config' (config table not found!))
I have only changed the stuff the instructable told me to change, and I have tried to look for faults myself but I cant find any... It's the first time I am using Lua, so this is totally new for me.
Hope somebody here can offer some help. Been stuck on this for days...
THIS PART OF THE PROBLEM IS SOLVED. CHECK COMMENTS FOR SOLUTION
Sadly when one problem is solved, a new one rises...
The chip is now successfully connecting to the wifi and mqtt service, but when I try to do the dry run by putting in the command 'step_move(1000,FWD,2)' nothing happens. The motor should rotate...
Also when I press the button I get a new panic error as follows:
PANIC: unprotected error in call to Lua API (button.lua:23: attempt to perform arithmetic on upvalue '?' (a nil value))
button.lua
--file button4.lua
do
-- use pin 1 as the input pulse width counter
local pin=5
local debounce = 150 --ms
local longpress = 2000 --ms
local pulse1, pulse2, du, now, trig = 1, 0, 0, tmr.now, gpio.trig
local prev_int_time, int_time, up_time = 0
local cal_steps = 100000
local cal_steps_dn = 0
local cal_steps_up = 0
local cal_state = 0 -- 0 = not calibration, 1 = calibrating down, 2 = calibrating up
state = 0 -- state: 0 = up, 1 = transition, 2 = down
gpio.mode(pin,gpio.INT)
local function pin4cb(level)
int_time = now() / 1000
if ((int_time - prev_int_time) > debounce) then
if (level == 0) then
up_time = int_time
else
if((int_time - up_time) > longpress) then
print("calibrating")
cal_state = 1
--cur_step = 100000
step_move(cal_steps,FWD,2)
else -- short press
print("short", cal_state)
if (cal_state == 2) then -- calibrated up (done)
print("calibration done")
state = 0 -- up
cur_step = 0
tot_steps = cal_steps - step_stepsleft
print("cal_steps: " .. cal_steps)
print("step_stepsleft: " .. step_stepsleft)
print("tot_steps: " .. tot_steps)
step_stop()
pins_disable()
cal_state = 0
if file.open("cfg_tot_steps.lua", "w+") then
file.write("tot_steps=" .. tot_steps .. '\n')
file.close()
end
elseif (cal_state == 1) then -- calibrated dn (switch direction)
print("calibration low point")
print(cal_steps - step_stepsleft)
step_stop()
step_move(cal_steps,REV,2)
cal_state = 2
elseif (cal_state == 0) then
if (state == 0 and step_stepsleft == 0) then -- i am up, go dowm
rollerblind.down()
-- state = 2
elseif (state == 1) then -- i am moving, do nothing
-- do nothing
elseif (state == 2 and step_stepsleft == 0) then -- i am down, go up
rollerblind.up()
-- state = 0
end
end
end
end
--print (level)
prev_int_time = int_time
end
end
gpio.trig(pin, "both", pin4cb)
end
Here is the code for the stepper.lua:
-- stepper.lua
-- code from: http://www.esp8266.com/viewtopic.php?f=19&t=2326
-- simple stepper driver for controlling a stepper motor with a
-- l293d driver
-- nodemcu pins: 0 5 6 7
stepper_pins = {1,3,2,4} -- (A-)blue, (A+)pink, (B-)yellow, (B+)orange
--stepper_pins = {1,2,3,4}
-- half or full stepping
step_states4 = {
{1,0,0,1},
{1,1,0,0},
{0,1,1,0},
{0,0,1,1}
}
step_states8 = {
{1,0,0,0},
{1,1,0,0},
{0,1,0,0},
{0,1,1,0},
{0,0,1,0},
{0,0,1,1},
{0,0,0,1},
{1,0,0,1},
}
step_states = step_states4 -- choose stepping mode
step_numstates = 4 -- change to match number of rows in step_states
step_delay = 10 -- choose speed
step_state = 0 -- updated by step_take-function
step_direction = 1 -- choose step direction -1, 1
step_stepsleft = 0 -- number of steps to move, will de decremented
step_timerid = 4 -- which timer to use for the steps
status_timerid = 2 -- timer id for posing of status messages
-- setup pins
function pins_enable()
for i = 1, 4, 1 do
gpio.mode(stepper_pins[i],gpio.OUTPUT)
end
end
function pins_disable()
-- for i = 1, 4, 1 do -- no power, all pins
for i = 2, 4, 1 do -- no power, all pins except one (to keep it in place)
gpio.mode(stepper_pins[i],gpio.INPUT)
end
end
-- turn off all pins to let motor rest
function step_stopstate()
for i = 1, 4, 1 do
gpio.write(stepper_pins[i], 0)
end
end
-- make stepper take one step
function step_take()
-- jump to the next state in the direction, wrap
step_state = step_state + step_direction
cur_step = cur_step + step_direction * FWD
if step_state > step_numstates then
step_state = 1;
elseif step_state < 1 then
step_state = step_numstates
end
-- write the current state to the pins
pins_enable()
for i = 1, 4, 1 do
gpio.write(stepper_pins[i], step_states[step_state][i])
end
-- might take another step after step_delay
step_stepsleft = step_stepsleft-1
if step_stepsleft > 0 then
-- if cur_step > 0 and cur_step < tot_steps and step_stepsleft > 0 then
tmr.alarm(step_timerid, 10, 0, step_take )
--tmr.alarm(step_timerid, 10, 0, step_take )
else
step_stopstate()
step_stop()
pins_disable()
mq.post_status()
if file.open("cfg_cur_step.lua", "w+") then
file.write("cur_step=" .. cur_step .. '\n')
file.close()
end
end
end
-- public method to start moving number of 'int steps' in 'int direction'
function step_move(steps, direction, delay)
tmr.stop(step_timerid)
step_stepsleft = steps
step_direction = direction
step_delay = delay
step_take()
end
function step_go_to(step, delay)
if step >= cur_step then
steps = step - cur_step
step_move(steps, FWD, delay)
end
if step <= cur_step then
steps = cur_step - step
step_move(steps, REV, delay)
end
end
function percent_go_to(percent, delay)
if(percent >= 0 and percent <= 100) then
step_stop()
tmr.register(status_timerid, 1000, tmr.ALARM_AUTO, function () mq.post_status() end)
tmr.start(status_timerid)
step = percent * tot_steps / 100
step_go_to(step, delay)
end
end
-- public method to cancel moving
function step_stop()
tmr.stop(step_timerid)
tmr.stop(status_timerid)
step_stepsleft = 0
step_stopstate()
end
Let's parse the error message one by one:
unprotected error in call to Lua API (wifi_setup.lua:25: bad argument #1 to 'config' (config table not found!))
Unprotected error means that you did a normal function call, as opposed to a protected call (aka pcall), which is a function call where you expect errors to occur and want to provide means to handle them. Since you did not do a protected call, Lua does not know how to handle the error and terminates right away (which is not a bad thing).
wifi_setup.lua:25 tells you the file and line at which the error occured.
bad argument #1 to 'config' means that the problem is due to the first argument passed to a function named config.
config table not found! is the error message provided by the implementer of that function.
So in summary, there is a problem with the function call wifi.sta.config(key,config.SSID[key]) as it expects a table as first argument, while you provided something different (ie. a string with the BSSID). Indeed checking with the NodeMCU docs shows that you need to pass a table to this function:
wifi.sta.config()
Sets the WiFi station configuration. [...]
Syntax
wifi.sta.config(station_config)
Parameters
station_config table containing configuration data for
station
The expected layout of the table is documented in detail on that page as well.
ComicSansMS provided a great answer the essence of which is that you need to replace
wifi.sta.config(key,config.SSID[key])
with
wifi.sta.config{ssid=key,pwd=config.SSID[key]}
Thus a standalone example could be like this:
--wifi.setmode(wifi.NULLMODE)
config = {}
config.SSID = {}
config.SSID["ssid"] = "password"
function wifi_wait_ip()
if wifi.sta.getip() == nil then
print("IP unavailable, Waiting...")
else
tmr.stop(1)
print("\n====================================")
print("ESP8266 mode is: " .. wifi.getmode())
print("MAC address is: " .. wifi.ap.getmac())
print("IP is " .. wifi.sta.getip())
print("====================================")
end
end
function wifi_start(list_aps)
if list_aps then
for key, value in pairs(list_aps) do
if config.SSID and config.SSID[key] then
wifi.setmode(wifi.STATION);
wifi.sta.config{ssid=key, pwd=config.SSID[key]}
-- wifi.sta.connect() not needed as config() uses auto-connect=true by default
print("Connecting to " .. key .. " ...")
tmr.alarm(1, 2500, 1, wifi_wait_ip)
end
end
else
print("Error getting AP list")
end
end
function start()
print("Configuring Wifi ...")
wifi.setmode(wifi.STATION)
wifi.sta.getap(wifi_start)
end
start()
I have recently been learning Lua with Love2d, so I decided to start making a simple RPG. It's quite simple. The console is where you play, and the extra window is where you can see your stats, equip items, ect.
But, I have run into a problem! Whenever I run the code, I see this main.lua:15: '=' expected near 'else'
I will include the code (all 3 files) below.
This is main.lua
function love.load()
love.graphics.setBackgroundColor( 255, 255, 255 )
require("player")
print("Enter your name")
pcStats.Name = io.read()
print("What class are you, " .. pcStats.Name .. "?")
pcStats.Class = io.read()
if pcStats.Class == "Ranger" then
os.execute("cls")
pcInv.InvSpace = 10
pcInv.Items.basicBow = Basic Bow
else
print("Error: Invalid Class. Please restart game")
end
print("What would you like to do? CODE END")
input = io.read()
end
function love.draw()
love.graphics.setColor( 0, 0, 0 )
love.graphics.print( "Level: " .. pcStats.Level, 1, 1 )
love.graphics.print( "Inv Space: " .. pcInv.InvSpace, 1, 20 )
love.graphics.print( "Inv: " .. pcInv.Items, 1, 40 )
end
Here is player.lua This is where the game variables are stored
pcStats = {}
pcStats.Level = 1
pcStats.XP = nil
pcStats.Name = nil
pcStats.Class = nil
pcStats.Atk = nil
pcStats.Def = nil
pcInv = {}
pcInv.InvSpace = nil
pcInv.Items.testsword = testing sword
And last but not least, here is the conf.lua used for love2d
function love.conf(t)
t.modules.joystick = true
t.modules.audio = true
t.modules.keyboard = true
t.modules.event = true
t.modules.image = true
t.modules.graphics = true
t.modules.timer = true
t.modules.mouse = true
t.modules.sound = true
t.modules.thread = true
t.modules.physics = true
t.console = true
t.title = "Lua RPG Alpha v0.0.1"
t.author = "Zach Herzer"
end
Line 15 is this:
pcInv.Items.basicBow = Basic Bow
Basic Bow isn't valid Lua code. I am pretty sure you meant something else - perhaps a string?
pcInv.Items.basicBow = "Basic Bow"
While we're at it,
pcInv.Items.testsword = testing sword
has a similar problem.